休眠。 QueryOver Take(n) - 使用 Left.Join
Posted
技术标签:
【中文标题】休眠。 QueryOver Take(n) - 使用 Left.Join【英文标题】:NHibernate. QueryOver Take(n) - with Left.Join 【发布时间】:2015-07-29 00:03:20 【问题描述】:将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
cmets。
为什么.Take(5)
也限制了cmets的数量?
如何达到预期的效果?
【问题讨论】:
这是一个经典的笛卡尔积问题。 NH 不会分页根,而是分页根 + 子级。就像 Radim 已经通过分页和延迟加载来回答 fetch parents 与批处理孩子一样 【参考方案1】:这里的重点是我们对分页的需求及其实现的不同。
虽然我们希望返回 5 个 root 元素,但 结果被转换成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
所以它最终可能只返回一个根实体,如果孩子(cmets)的数量是 5+
解决方案?我建议这样做:
只选择root实体 使用批量提取加载子项只选择根,也可能意味着选择任何多对一/引用。这将最终形成一个星型模式结构,左连接将再次正确地在根实体上分页。
文档中描述了批量获取:
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?【讨论】:
感谢您的详细解答。感谢您的帮助++ 很高兴看到这一点,先生!享受很棒的 NHibernate ;)以上是关于休眠。 QueryOver Take(n) - 使用 Left.Join的主要内容,如果未能解决你的问题,请参考以下文章
LINQ 查询添加 orderby 使 Skip 和 Take 不起作用 Linqpad