NHibernate一对多使用LazyLoad off导致n + 1查询

时间:2013-06-25 05:07:05

标签: nhibernate nhibernate-mapping lazy-loading

我正在尝试关闭延迟加载NHibernate中的一对多映射。我在我的实体映射类中有以下映射。一个实体有很多地址,我正在寻找的是一个基本上将基表连接到Addresses表的查询,并在一个请求中返回所有结果。相反,我看到为基表中的每条记录提交了一系列sql查询到数据库。

HasMany(m => m.Addresses).Not.LazyLoad().Fetch.Join();

我需要一种完全关闭延迟加载的方法。

3 个答案:

答案 0 :(得分:3)

我强烈建议您阅读Ayende撰写的这篇博文: NHibernate is lazy, just live with it

使用ORM并试图避免懒惰......将无法正常工作。例如,在地址的情况下,您将丢失分页。

  

(通过连接获取它们时,会发生什么?如果有实体10   地址,你会要求前10条记录......你会得到的   一。如果你要求11 ......)

,情况会更糟

但你可以使用的是NHibernate的力量:19.1.5. Using batch fetching

HasMany(m => m.Address)
 ...
.Fetch.Select()
.BatchSize(25)

现在,如果您需要25条记录,则会有2个SELECT。首先是实体,第二个是所有相关的地址。这是改进,而ORM的所有优势仍然存在。

答案 1 :(得分:2)

我认为这样就足够了:

HasMany(m => m.Addresses).Not.LazyLoad();

要使用select获取数据,您应该明确使用“Fetch”:

session.QueryOver<Item>()
   .Fetch(item => item.Addresses).Eager
   .Take(1000)
   .TransformUsing(Transformers.DistinctRootEntity)
   .List();

答案 2 :(得分:1)

我假设您使用HQL,Linq或纯SQL查询加载基本实体。这些查询忽略映射中的“连接”提取设置。您必须在查询中显式获取地址或使用Get / Criteria / QueryOver。

参考文档:http://nhibernate.info/doc/nh/en/index.html#performance-fetching-custom