【问题标题】:nHibernate Eager Loading at runtimenHibernate Eager Loading 在运行时
【发布时间】: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


【解决方案1】:

【讨论】:

  • 最后,我们决定不使用 EagerFetch 解决方案,尽管它确实有效。我们通过允许 LazyLoading 并将 UnitOfWorkScope 从服务层向上移动到业务层来简化方法。另外 - 如果您使用 NServiceBus,请不要忘记它会使用 IsolationLevel.Serializable 为您创建环境事务,如果您希望数据库操作使用 ReadCommitted,则该事务将不起作用。您必须将 NSB 配置为使用 ReadCommitted,然后一切顺利。
猜你喜欢
  • 2011-03-14
  • 2013-06-01
  • 2018-11-16
  • 2011-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-09
相关资源
最近更新 更多