【发布时间】:2012-07-10 19:38:11
【问题描述】:
我们正在使用 NCommon 的 UnitOfWorkScope,它包装了 nHibernate ISession 功能。我们的目标是按需预先加载复杂的属性,而不是总是通过配置预先加载它们。这个想法是,可以通过调用代码对检索实体的给定服务进行一些自定义 - 有时我们只希望父实体被水合,其他时候我们可能也希望复杂的子属性也被水合。
为此,我们正在执行以下操作:
var iSession = unitOfWorkScope.CurrentUnitOfWork<NHUnitOfWork>().GetSession<ParentEntity>();
iSession.CreateCriteria<ParentEntity>().SetFetchMode("Children", FetchMode.Eager);
在会话中设置好之后,我们使用 NCommon 的 IRepository 功能来检索实体:
var parent = parentRepository.FirstOrDefault(x => x.Id == 123);
但是,当我们检查 parent.Children 集合时,我们会得到:
NHibernate.Collection.Generic.PersistentGenericBag<ChildEntity>
... 这告诉我没有发生 Eager-loading。当我们修改 NH 映射以始终强制进行急切加载时,我们可以正确地看到子节点。
有人能解释一下吗?我认为我们错过了一些东西,因为 FetchMode.Eager 被忽略了。
【问题讨论】:
-
对不起,你为什么假设没有发生预加载?这是 NHibernate 用于包的类。
-
因为没有填充 Children 属性。当我们通过 config 配置 Eager 加载时,我们总是会得到一个填充的 Children 集合,但是当我们尝试在运行时通过 ISession 上的 FetchMode 执行此操作时,我们会得到 PersistentGenericBag,它在访问时会引发 LazyInitializationException。
-
似乎 NH 的 Session.Query
() 不遵守已通过调用 CreateCriteria() 在 Session 上创建的条件。我认为在调用 Query() 时会尊重对它的调用,但显然不是...... ??? -
为什么不对整个业务事务保持会话打开?调用代码和存储库之间是否存在网络边界?如果是这样,您应该使用 dto。
标签: nhibernate fluent-nhibernate ncommon