如何获取每个实体的所有子项的前20个父实体

时间:2011-10-03 20:24:14

标签: nhibernate linq-to-nhibernate fetch eager-loading

我有一个聚合根,它是一个WallPost。 WallPost可以包含零到多个WallPostComments。

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

我尝试过使用NHibernate Linq和Fetch()子句,但这会导致“使用collection 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个墙上的帖子及其相关注释,但查询以两个选项执行,其中第二个选择将WallPost连接到WallPostComment,有效地撤回所有墙帖和评论(仅通过WallPostId)。这个工作正常,但有少量帖子 - 但我无法想象这种缩放很好。

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

1 个答案:

答案 0 :(得分: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);

要记住的重要事项是使用“subselect”提取策略映射评论集合。