Nhibernate 如何获取前20个父实体以及每个实体的所有子实体

Nhibernate 如何获取前20个父实体以及每个实体的所有子实体,nhibernate,linq-to-nhibernate,fetch,eager-loading,Nhibernate,Linq To Nhibernate,Fetch,Eager Loading,我有一个聚合根,它是一个墙柱。一个WallPost可以有零到多个WallPost命令 我想写一个查询来获取20个墙贴(按DateCreated降序排序),并急切地获取这20个墙贴的所有评论 我尝试使用NHibernate Linq和Fetch()子句,但这会导致“firstResult/maxResults指定集合Fetch;在内存中应用!”错误 我尝试过的其他两种方法是: var wallPostQuery = _session.QueryOver<WallPost>()

我有一个聚合根,它是一个墙柱。一个WallPost可以有零到多个WallPost命令

我想写一个查询来获取20个墙贴(按DateCreated降序排序),并急切地获取这20个墙贴的所有评论

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

我尝试过的其他两种方法是:

var wallPostQuery = _session.QueryOver<WallPost>()
            .Where(x => x.WallId == wallId)
            .OrderBy(x => x.DateCreated)
            .Desc
            .Left.JoinQueryOver(x => x.Comments)
            .Take(20)
            .Future<WallPost>();
var wallPostQuery=\u session.QueryOver()
.其中(x=>x.WallId==WallId)
.OrderBy(x=>x.DateCreated)
.描述
.Left.JoinQueryOver(x=>x.Comments)
.Take(20)
.Future();
但是,令人惊讶的是(好吧,不是真的),这带来了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();
var wallPostQuery=\u session.QueryOver().Where(x=>x.WallId==WallId).OrderBy(x=>x.DateCreated.Desc.Take(20).Future();
_session.QueryOver().Where(x=>x.WallId==WallId).Left.JoinQueryOver(x=>x.Comments.Future();
var wallPosts=wallPostQuery.ToList();
这给了我20个带有相关注释的墙柱,但查询是作为两个选择执行的,第二个选择将墙柱连接到墙柱,有效地收回所有墙柱和注释(仅通过墙柱ID过滤)。虽然有少量的帖子,但这种方式很好用——但我无法想象这种扩展会有多好

一定有更好的办法,但我似乎想不出来。有什么建议吗?

我认为我发现的类似(稍微复杂一点)问题可能会对您有所帮助。
大致如下:

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 wallPostIdsQuery=\u session.QueryOver().Where(x=>x.WallId==WallId).OrderBy(x=>x.DateCreated.Desc.Take(20).Future()
.选择(p=>p.Id);
var wallPostsQuery=_session.QueryOver().WithSubquery.WhereProperty(p=>p.Id).In(wallpostedsquery);
var commentsQuery=_session.QueryOver().WithSubquery.WhereProperty(p=>p.WallPostId).In(wallPostIdsQuery);
if(wallPostsQuery.Count()==0)
{
返回wallPostsQuery.List();
}
初始化(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);
var wallPostQuery=\u session.QueryOver().Where(x=>x.WallId==WallId).OrderBy(x=>x.DateCreated.Desc.Take(20).Future();
初始化(wallPostQuery.First().Comments);

要记住的重要一点是使用“subselect”获取策略映射评论集合。

感谢您的帮助。这是可行的(我使用了你建议的较短版本),尽管NHibernate探查器抱怨选择N+1(因为NHibernateUtil.Initialize会进行10次后续选择),但我对这比我自己的解决方案更满意。现在-我注意到,为获取注释而生成的SELECT语句一次获取两篇文章的注释:WHERE comments0_.WallPost_id in(193192)。有没有办法一次把它们都取出来?这似乎很奇怪;注释集合是否映射了子选择策略?嗯。。。不,我得到的只是:var wallPostQuery=\u session.QueryOver().Where(x=>x.WallId==WallId).OrderBy(x=>x.DateCreated.Desc.Take(20.Future();初始化(wallPostQuery.First().Comments);映射中的抓取策略呢?哈哈!它被设置为批处理,大小为“2”。哦!我把它改为subselect,一切都很好。非常感谢你的帮助!