【问题标题】:NHibernate - Problems Eager Loading EntitiesNHibernate - 急切加载实体的问题
【发布时间】:2017-09-28 17:51:48
【问题描述】:

我在 NHibernate 中使用 Eager Loading 时遇到了一些问题。在开始维护此应用程序时,我注意到的第一件事是它们似乎并没有在任何地方急切加载。

我的第一个停靠点是 Fetch。但这引发了一个异常,即当集合是 IList 时它无法完成该操作。显然它必须是一个ICollection。我几乎无法更改域,只是为了适应 F​​etch。

接下来,我查看了 .Future 和 .FutureValue。不去那里,因为提供商不支持它。

这给我留下了 NHibernateUtil.Initialize。作为概念证明,我写了一些代码,例如:

var leppp = _repository.Query<LogbookEntryProcedure>()
    .Where(lep => lep.LogbookEntry.Id == logbookEntryId);

NHibernateUtil.Initialize(leppp.Select(l => l.Complications));
NHibernateUtil.Initialize(leppp.Select(l => l.Magnitude));
NHibernateUtil.Initialize(leppp.Select(l => l.Outcome));
NHibernateUtil.Initialize(leppp.Select(l => l.FollowUps));

var lepp = leppp.Single();    

它没有抛出异常。但是,它似乎并没有急于加载任何东西。当我查看 Profiler 时,我可以看到正在对相关对象的数据库进行往返。

那么,在这种情况下,如何在 NHibernate 中进行预加载?

【问题讨论】:

  • “他们似乎并不急于在任何地方加载”:是的,这是 NHibernate 的常见做法。甚至recommended practice by a bunch of people 包括me。正确设置的 NHibernate 应用程序不会遇到 N+1 延迟加载问题。它的代码库更轻,甚至可能在运行时性能上胜过急切加载。通过访问之前的链接了解更多信息。

标签: nhibernate


【解决方案1】:

正如我的comment 中所述,切换到预加载可能不是一个好举措。现在回到你的问题主题。

关于Fetch:我不知道有这样的限制。您是否尝试过使用FetchMany 代替?您可以提供确切的错误信息吗?您使用的是旧的 NHibernate 版本吗?

FutureFutureValue 不支持:嗯,您使用哪个版本的 NHibernate?它在那里:NH-2309,在 NHibernate v3 中完成。 (当前版本是 v4.1.1。需要 .Net Framework 4,如果您的应用程序不针对它,请升级到 v3。请注意,Linq 提供程序不再是外部依赖项,因为 v3,它是嵌入式的,只有一个 using NHibernate.Linq; .)

NHibernateUtil.Initialize:它不适用于IQueryable。这样做只是无操作。 Initialize 检查提供的对象是实体代理还是集合代理,如果是,则对其进行初始化。否则它什么也不做,因为这可能是一个集合或实体,它直接加载而没有先被代理。 Queryables 不是代理。
(这再次强化了我的信念,您应该阅读更多关于 NHibernate 如何使用延迟加载的信息,因为此实用程序方法已记录用于代理的使用,并且代理用于延迟加载. 特别检查"Improving Performances - Using batch fetching",确实是“批量延迟加载”。)

因此,如果您真的需要使用 Linq 进行即时获取,同时使用旧版本的 NHibernate ( 升级 NHibernate、更改您的域模型或更改您的查询 API。

【讨论】:

  • 谢谢。我会回去做更多的实验。我会阅读您提供的链接。干杯。
猜你喜欢
  • 1970-01-01
  • 2011-04-02
  • 2017-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-16
相关资源
最近更新 更多