将 Take()
与 join 一起使用时出现一些奇怪的行为。假设以下示例:
Comment comment = null;
var persons = _repository
.QueryOver()
.Left.JoinAlias(x => x.Comments, () => comment)
.Where(x => x.Age > 20)
.Take(5)
.Future()
.ToList();
嗯,我希望数组中存在 5
个人,并且每个人都有一个包含 N 个评论
的列表。
但是,结果给出了 5
个人,最多有 5
条评论。
为什么.Take(5)
也限制评论数量?
如何达到想要的结果?
最佳答案
这里的重点是我们对分页的需求及其实现的不同。
- 虽然我们期望返回 5 个根元素,
- 结果转换为 5 行,5 个选定行:
在这个问答中可以找到一些线索: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,最终可能只返回一个根实体
解决方案?我建议这样做:
- 仅选择根实体
- 使用批量抓取来加载子项
仅选择根,可能意味着还选择任何多对一/引用。这将最终形成星型模式结构,通过左连接将再次正确地对根实体进行分页。
文档中描述了批量获取:
19.1.5. Using batch fetching
一些类似的问题:
关于NHibernate。 QueryOver Take(n) - 使用 Left.Join,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30287018/