7

我在加载集合时遇到问题。我的设置是简单的一对多关联,使用 FluentNHibernate 映射。实体被加载并没有抛出异常,但访问相关集合显示“非法访问加载集合”。我将在此处粘贴相关部分的代码。

[Serializable]
[DataContract(IsReference = true)]
public partial class Department : Entity
{
    ...
    [DataMember]
    public virtual IList<PressJobRun> PressJobRun
    {
        get { return pressJobRunField; }
        protected set { pressJobRunField = value; }
    }
    ...
}

映射如下

public DepartmentMap()
{
    Id(x => x.Id);
    Map(x => x.Name)
        .Not.Nullable()
        .Length(100);
    HasMany(x => x.PressJobRun)
        .AsBag()
        .Inverse()
        .Cascade.AllDeleteOrphan()
        .LazyLoad()
        .BatchSize(50);
    ...
}

我还尝试通过排除该行和调用来禁用延迟加载,.Not.LazyLoad()但是 end 是相同的。

    using (var tx = m_Repository.Session.BeginTransaction())
    {
        var depts = m_Repository.Session.CreateCriteria<Department>().List<Department>();
        var dept = depts[0];
        ...
    }

我意识到公开会话不是要做的事情,但这是为了确保会话是打开的。

当我深入研究异常时,我看到以下堆栈跟踪:

   at NHibernate.Collection.AbstractPersistentCollection.Initialize(Boolean writing)
   at NHibernate.Collection.AbstractPersistentCollection.Read()
   at NHibernate.Collection.AbstractPersistentCollection.ReadSize()
   at NHibernate.Collection.PersistentBag.get_Count()
   at NHibernate.DebugHelpers.CollectionProxy`1.get_Items()

The interesting gremlin comes here. I've set breakpoint on setter line of PressJobRun property.

  • if I step over it and quick watch pressJobRunField, I see the "illegal access to loading exception".
  • if I first quick watch value variable, I see the loaded collection. Stepping over setter line works as expected.

What I use

  • Visual Studio 2012, targeting .NET 4
  • NHibernate 3.3.1.400
  • SQL CE 4
  • Castle
  • Castle AutoTx facitlity
  • I manage session per WCF request myself

What I've tried

  • disabling lazy loading
  • made sure that session is open, and that it's same session during execution of offending code
  • toggled Inverted map of collection (thought I believe it should be inverted)
  • cleaned and rebuilt solution
  • made sure in Configuration Manager that all projects in solution are being built
  • set debugger to break on all thrown exceptions. Debugger doesn't break with exception that i see set in collection
4

1 回答 1

3

Problem is that when PressJobRub.Department property is set, my code also adds the PressJobRun to appropriate collection in Department. I did initialize the collection, but problem was that the collection which NHibernate uses fails for some reason when calling Contains() method. I'm still in wonder about gremlin I described in the question, and why the debugger didn't break on exception when I unticked 'Enable just my code debugging' and set it to break on Thrown exceptions too.

Anyhow, solution is to map PressJobRun.Department access to field (in my case to Access.PascalCaseField(Prefix.mUnderscore)) in order to avoid call that adds the entity to Department.PressJobRun collection.

Krzysztof Kozmic's article explained this, although in my case collection wasn't uninitialized.

于 2012-08-01T14:00:19.030 回答