【问题标题】:NHibernate Lazy="Extra"NHibernate 懒惰=“额外”
【发布时间】:2011-02-22 15:15:29
【问题描述】:

关于lazy="extra" 到底能做什么有很好的解释吗?

我看到的所有帖子都只是重复这样一个事实,即它将对 MyObject.ItsCollection.Count 的引用转换为 select count(*) 查询(假设它们尚未加载)。

我想知道它是否能够做更强大的事情,比如将 MyObject.ItsCollection.Any(o => o.Whatever == 5) 变成 SELECT ...EXISTS 查询。

docs 的第 18.1 节仅涉及它。我不是 NH 开发人员,所以如果不做一些工作来设置所有内容,我就无法真正尝试它并观看 SQL Profiler;我只是在寻找某种参考来描述此功能的功能。

谢谢!

【问题讨论】:

  • 当 Any() 迭代集合时,它通过 IEnumerable 接口进行。 NHibernate 无法知道迭代是由 Any() (或 Where() 或其他)执行的,因此别无选择,只能获取所有元素。它无法检测到谓词。

标签: nhibernate


【解决方案1】:

对于 2.x 版本,它仅用于将 collection.Count() 转换为 select count,据我在源代码中所见,它还允许构造 collection[5] 获取该特定实体(使用索引 5) 而不是为整个集合补水。

对于版本 3.x,我在发行说明中没有看到任何相关内容

【讨论】:

  • 哇 - 感谢您为我检查源代码(!!!)。这是否记录在任何地方,供我自己将来参考??
  • 将 nhibernate 引用视为白名单(但也请务必阅读发行说明,见下文):虽然其他各种未记录的内容可能有效,但只有在引用中明确命名的内容才是受支持的功能。因此,当参考资料说额外的惰性是为了在集合中有效地获取单个元素时,这就是您应该期待的。检查 17.1。获取策略。它提到了个人获取,但没有提到计数“黑客”。但是,发行说明包括它。我个人不使用它,在我的场景中它有问题,我更喜欢 ISession.CreateFilter() 机制
  • 我们有什么理由不想将lazy="extra" 设置为所有内容吗?我不明白为什么我们不这样做,因为似乎没有与使用额外费用相关的成本,而不仅仅是真的?
  • @sp1ky 如果集合很小,并且您经常访问它的多个成员,lazy=extra 将导致额外的数据库往返。
【解决方案2】:

刚刚尝试在使用lazy="extra" 映射的集合Customer.Orders 上调用Any()

customer.Orders.Any()

生成的 SQL 语句看起来像这样(简化):

SELECT *
FROM Order
WHERE CustomerId = 120

而打电话时

customer.Orders.Count > 0

生成的 SQL 如下所示:

SELECT count(*)
FROM Order
WHERE CustomerId = 120

【讨论】:

  • 所以你必须使用.Count()而不是.Any()?
  • @MattKocaj Count 不是 Count()
【解决方案3】:

lazy = extra 允许计算集合的元素而不需要获取它,因为惰性实体用代理装饰,当客户端代码请求集合上的 .Count 时,正确的“@987654322 @" 向数据库发出查询。如果没有lazy=extra,则从数据库中读取集合。

【讨论】:

  • 感谢您的回答。我知道你提到的行为。我正在寻找某种文档来展示它能够处理的一些更强大的案例(如果有的话)——比如处理 Any() 调用并将其转换为 EXISTS 查询。
  • 抱歉弄错了您的问题。但是您描述的行为并不适用。也许 nh linq 提供者有能力。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-09
  • 2012-06-02
相关资源
最近更新 更多