具有SetMaxResults或N + 1 SELECT的DistinctRootEntityTransformer

时间:2011-05-10 07:41:02

标签: nhibernate

我已经把这个问题发给了nh小组,但仍然没有得到答案,所以我在这里发帖。 我有一个问题,急切加载子集合,并使用SetMaxresults分页获得正确的结果。

假设我有一个简单的实体:

 public class Post
{
                int Id {get; set;}
                Vote Votes {get; set;}
}

public class Vote
{
                int Id {get; set;}
}

一开始我有一个延迟加载的投票集合,除了N + 1 SELECT语句之外它运行良好。

然后我试图热切地获取“投票”收藏效果不错,但在数据库方面有重复(如果一个帖子有3个投票,我们将在得到的SQL查询中有3行)我使用DistinctRootEntityTransformer也很好除了SetMaxResults。因为SetMaxResults限制了数据库端的结果,所以在应用DistinctRootEntityTransformer之后,在对象端预期的结果会更少。

我查看了博客文章,StackOverflow问题,尝试了许多内容,如Fetch,LeftOuterJoins,Subqueries,分离标准,但没有找到任何解决方案。此问题也在此处进行了描述http://www.interworks.com/blogs/banderton/2009/06/26/nhibernate-eager-loading-collections-rootentityresulttransformer-and-setm

现在我看到三个解决方案,使用setMaxResults获取不正确的结果编号,保留SELECT N + 1,或者在延迟加载的“投票”集合上设置批量大小,这就是我所做的。最新问题是NHProf为批量选择产生“无限结果集”警报,因为它不是最佳选择。

也许我错过了什么。有没有解决方案可以解决它?

提前致谢,

1 个答案:

答案 0 :(得分:2)

我会保持延迟加载并尝试将batch size添加到您的映射中以简化选择n + 1问题。

<bag name="Votes" cascade="all" batch-size="20">
..
</bag>

基本上将batch-size设置为20会将发送到数据库的查询量减少20倍。如果没有设置,如果你有99行,你会发出99个查询到数据库,批量大小设置你会发出5。

急切加入会产生Cartesian join,因此分页将不正确。另请注意,DistinctRootEntity仅在数据库本身上提供客户端数据NOT的过滤。