NHibernate集合加载,“非法访问加载集合”

时间:2012-08-01 11:02:21

标签: 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; }
    }
    ...
}

映射如下

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()来禁用延迟加载,但结尾是相同的。

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

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

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

   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()

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

  • 如果我跨过它并快速观看pressJobRunField,我会看到“非法访问加载例外”。
  • 如果我第一次快速查看value变量,我会看到已加载的集合。踩过setter线可以按预期工作。

我用的是什么

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

我尝试了什么

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

1 个答案:

答案 0 :(得分:3)

问题是,当设置PressJobRub.Department属性时,我的代码还会将PressJobRun添加到Department中的相应集合中。我做了初始化集合,但问题是NHibernate在调用Contains()方法时由于某种原因使用的集合失败了。我仍然对我在问题中描述的gremlin感到好奇,以及当我取消选中“启用我的代码调试”并将其设置为时,调试器为什么没有中断异常抛出例外。

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

Krzysztof Kozmic's article解释了这一点,虽然在我的案例中,收集并未未初始化。