2011-10-03 47 views
0

我有一个聚合根,它是一个WallPost。 WallPost可以有零到多个WallPostComments。如何为每个实体获取包含所有子项的父实体的前20位

我希望编写一个查询来获取20个墙贴(按DateCreated降序排列),并且还热切地获取这20个墙贴的所有评论。

我尝试过使用NHibernate Linq和Fetch()子句,但是这会导致“使用集合提取指定的firstResult/maxResults;在内存中应用!”错误。我试过其他

有两种方法:

var wallPostQuery = _session.QueryOver<WallPost>() 
      .Where(x => x.WallId == wallId) 
      .OrderBy(x => x.DateCreated) 
      .Desc 
      .Left.JoinQueryOver(x => x.Comments) 
      .Take(20) 
      .Future<WallPost>(); 

但是,意外的惊喜(当然,不是真的)这个带回每个零或一个评论20个涂鸦墙。我得到了重复的墙贴,这不是我想要的。

一个更好的查询是

var wallPostQuery = _session.QueryOver<WallPost>().Where(x => x.WallId == wallId).OrderBy(x => x.DateCreated).Desc.Take(20).Future<WallPost>(); 

_session.QueryOver<WallPost>().Where(x => x.WallId == wallId).Left.JoinQueryOver(x => x.Comments).Future<WallPost>(); 

var wallPosts = wallPostQuery.ToList(); 

这给了我与他们相关的注释20个涂鸦墙,但查询以2种选择,其中第二选择加入WallPost到WallPostComment,有效地拉回所有墙执行帖子和评论(仅由WallPostId过滤)。这可以很好地工作,但有很少的帖子 - 但我无法想象这个缩放非常好。

必须有更好的方法 - 但我似乎无法弄清楚。有什么建议么?

回答

1

我认为我发现的solution类似(更复杂一点)的问题可能会对您有所帮助。
东西沿着线:

var wallPostIdsQuery = _session.QueryOver<WallPost>().Where(x => x.WallId == wallId).OrderBy(x => x.DateCreated).Desc.Take(20).Future<WallPost>() 
.Select(p => p.Id); 

var wallPostsQuery = _session.QueryOver<WallPost>().WithSubquery.WhereProperty(p => p.Id).In(wallPostIdsQuery); 

var commentsQuery = _session.QueryOver<WallPostComment>().WithSubquery.WhereProperty(p => p.WallPostId).In(wallPostIdsQuery); 

if (wallPostsQuery.Count() == 0) 
{ 
    return wallPostsQuery.List(); 
} 

NHibernateUtil.Initialize(wallPostsQuery.First().Comments); 

,或者可能只是这两个线 -

var wallPostQuery = _session.QueryOver<WallPost>().Where(x => x.WallId == wallId).OrderBy(x => x.DateCreated).Desc.Take(20).Future<WallPost>(); 
NHibernateUtil.Initialize(wallPostQuery.First().Comments); 

,重要的是要记住的意见收集与“再选择”抓取策略映射。

+0

感谢您的帮助。这工作(我用你的建议较短的版本),虽然NHibernate的Profiler抱怨SELECT N + 1(因为NHibernateUtil.Initialize做了10次后续选择),我比这更喜欢我自己的解决方案。现在 - 我注意到,用于获取注释的SELECT语句一次获取两个帖子的这些语句:WHERE comments0_.WallPost_id(193,192)。有没有办法一次抓取它们? –

+0

这看起来很奇怪;是使用子选择策略映射的评论集合? –

+0

嗯...不,我得到的是这个:var wallPostQuery = _session.QueryOver ().Where(x => x.WallId == wallId).OrderBy(x => x.DateCreated).Desc。拿(20)。未来(); NHibernateUtil.Initialize(wallPostQuery.First()。Comments); –

相关问题