【问题标题】:NHibernate. QueryOver Take(n) - with Left.Join休眠。 QueryOver Take(n) - 使用 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 与批处理孩子一样

标签: nhibernate fluent-nhibernate queryover


【解决方案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 ;)
猜你喜欢
  • 2015-04-16
  • 1970-01-01
  • 2012-03-17
  • 2011-05-24
  • 1970-01-01
  • 1970-01-01
  • 2011-03-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多