NHibernate集合加载,"非法访问加载集合"

Nik*_*vić 7 nhibernate fluent-nhibernate

我在加载集合时遇到问题.我有简单的一对多关联,使用FluentNHibernate进行映射.实体加载时会抛出异常,但访问相关集合会显示" 非法访问加载集合 ".我会在这里粘贴相关的代码部分.

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

映射如下

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);
    ...
}
Run Code Online (Sandbox Code Playgroud)

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

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

我意识到暴露会话不是要做的事情,但这是为了确保会话是开放的.

当我向下钻取异常时,我看到以下堆栈跟踪:

   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()
Run Code Online (Sandbox Code Playgroud)

有趣的gremlin来到这里.我在setter PressJobRun属性行上设置了断点.

  • 如果我跨过它并快速观看pressJobRunField,我会看到" 非法访问加载异常 ".
  • 如果我第一次快速观察value变量,我会看到加载的集合.踩过setter线按预期工作.

我用的是什么

  • Visual Studio 2012,面向.NET 4
  • NHibernate 3.3.1.400
  • SQL CE 4
  • 城堡
  • Castle AutoTx facitlity
  • 我自己管理每个WCF请求的会话

我试过的

  • 禁用延迟加载
  • 确保会话是开放的,并且在执行违规代码期间它是相同的会话
  • 切换Inverted的收集地图(以为我认为它应该倒置)
  • 清理和重建解决方案
  • 在Configuration Manager中确保正在构建解决方案中的所有项目
  • 设置调试器以中断所有抛出的异常.调试器不会破坏我在集合中看到set的异常

Nik*_*vić 4

问题是,当PressJobRub.Department设置属性时,我的代码还将添加PressJobRunDepartment. 我确实初始化了集合,但问题是 NHibernate 使用的集合在调用Contains()方法时由于某种原因失败。我仍然想知道我在问题中描述的 gremlin,以及为什么当我取消选中“仅启用我的代码调试”并将其设置为在引发异常时中断时,调试器没有在异常时中断。

无论如何,解决方案是将访问映射PressJobRun.Department到字段(在我的例子中是Access.PascalCaseField(Prefix.mUnderscore)),以避免将实体添加到Department.PressJobRun集合中的调用。

Krzysztof Kozmic 的文章解释了这一点,尽管在我的例子中,集合并不是未初始化的。