我在加载集合时遇到问题。我有简单的一对多关联,使用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线可以按预期工作。我用的是什么
我尝试了什么
Inverted
收集地图(我认为应该倒置)答案 0 :(得分:3)
问题是,当设置PressJobRub.Department
属性时,我的代码还会将PressJobRun
添加到Department
中的相应集合中。我做了初始化集合,但问题是NHibernate在调用Contains()
方法时由于某种原因使用的集合失败了。我仍然对我在问题中描述的gremlin感到好奇,以及当我取消选中“启用我的代码调试”并将其设置为时,调试器为什么没有中断异常抛出例外。
无论如何,解决方案是将PressJobRun.Department
访问字段(在我的情况下为Access.PascalCaseField(Prefix.mUnderscore)
)映射,以避免将实体添加到Department.PressJobRun
集合的调用。
Krzysztof Kozmic's article解释了这一点,虽然在我的案例中,收集并未未初始化。