N 休眠。 QueryOver Take(n) - Left.Join

NHibernate. QueryOver Take(n) - with Left.Join

Take() 与联接一起使用时出现一些奇怪的行为。假设下面的例子:

Comment comment = null;
var persons = _repository
        .QueryOver()
        .Left.JoinAlias(x => x.Comments, () => comment)
        .Where(x => x.Age > 20)
        .Take(5)
        .Future()
        .ToList();

好吧,我希望数组中有 5 个人,并且他们每个人都有一个列表 N comments

但是,结果给出 5 人,最多 5 条评论。

为什么.Take(5)也要限制评论数?

如何达到想要的效果?

这里的重点是我们对分页的需求及其实现的不同。

  • 虽然我们期望返回 5 个 root 个元素,但
  • 结果被转换为 5 , 5 selected行:

在这个问答中可以找到一些线索:NHibernate QueryOver with Fetch resulting multiple sql queries and db hits

如果使用 SQL Server 2012 dialect 进行分页,我们会看到 SQL 是这样的:

SELECT ...
FROM root
JOIN collection
WHERE....
OFFSET 0 ROWS -- skip 0 or 10 or 20 rows
FETCH NEXT 5 ROWS ONLY; -- take 5 rows

因此,如果子项(评论)的数量为 5+

,那么最终可能只返回一个根实体

解决方案?我建议这样做:

  • select 只是 root 实体
  • 使用批量抓取加载子项

只选择 root,可能意味着 select 也可能是任何 many-to-one/Reference。这将以星型模式结构结束,左连接将再次正确地在根实体上分页。

文档中描述了批量获取:

19.1.5. Using batch fetching

一些类似的问题:

  • NHibernate: Select one to Many Left Join - Take X latest from Parent
  • How to Eager Load Associations without duplication in NHibernate?