使用 NHibernate 3.0 QueryOver 或 LINQ 提供程序的权衡

Posted

技术标签:

【中文标题】使用 NHibernate 3.0 QueryOver 或 LINQ 提供程序的权衡【英文标题】:Tradeoffs using NHibernate 3.0 QueryOver or LINQ provider 【发布时间】:2010-10-06 15:13:04 【问题描述】:

与使用 QueryOver 语法相比,我还没有发现 NHibernate 3.0 LINQ 提供程序所支持的内容的明确比较。从表面上看,这似乎是两个非常相似的事情的两个巨大的努力。

使用每种方法的关键权衡是什么?

【问题讨论】:

我很想看到一个很好的比较。 【参考方案1】:

LINQ 和 QueryOver 是完全不同的查询方法,是在 NHibernate 2 (Criteria, HQL, SQL) 中添加的查询方法

QueryOver 是 Criteria 的强类型版本,并且支持几乎相同的构造,它们是 NHibernate 特有的。

LINQ 是一种“标准”查询方法,这意味着客户端代码可以在 IQueryable 上运行,而无需显式引用 NHibernate。它支持一组不同的结构;很难说是否比 QueryOver 有更多或更少。

我的建议是学习所有支持的查询方法,因为每个用例都不同,有些用例更好,有些用另一种更好。

【讨论】:

LINQ Provider 似乎支持获取和缓存,我只是想知道是否会有任何类似的技术墙(加入场景等)可以遇到。 例如,LINQ 还不支持左连接。 在我看来,用于连接的 Linq 语法非常丑陋,并导致代码不可读。这就是我使用 Criteria API 和 QueryOver 的原因。 NH 的 linq 实际上不是基于标准/QueryOver 吗? Linq不可能有更多的功能。它只能有更少。 @Stefan:不,实际上不是。尽管新的供应商比旧的供应商要好得多(这真的很差),但距离完善还很远。事实上,在 NH3-release 之前已经有一些讨论,是否应该将 LINQ-support 称为“Beta” - 这样做有充分的理由。然而,Fabio Maulo 似乎决定不称其为不完整的测试版。【参考方案2】:

我同时使用了 NH-Linq-providers(2.1 版的旧 NHContrib,以及 NH3.0 的新版),还使用了 QueryOver。凭借在开发相当复杂的数据驱动应用程序期间获得的所有经验,如果您打算仅支持基本的 CRUD 操作,我强烈建议不要将现有的 linq-provider 与 nHibernate 一起使用!

当前的实现 (linq) 有时会产生非常不可读且效率低下的 SQL。如果您想优化数据库性能,尤其是快速连接一些表会成为一场噩梦。

尽管存在所有这些缺点,但我从未遇到过错误的查询。 因此,如果您不关心性能并且已经熟悉 LINQ,那么请选择 NH-Linq。否则 QueryOver 是您可靠且类型安全的朋友。

【讨论】:

一个真实的例子:Query 的一项任务耗时 10 秒。更改为QueryOver,没有任何其他更改:1s @BenjaminSchmid 如果您可以显示该查询会很好,即使更改名称等只是为了了解可能需要更长时间的粗略复杂性【参考方案3】:

LINQ to NHibernate(从 3.0 版开始)不支持 Nullable 类型的 .HasValue 属性。必须在查询中与 null 进行比较。

【讨论】:

【参考方案4】:

我开始使用 NH-Linq,因为我已经完成了 LinqToSql 和实体框架。但是,对于更复杂的查询,我总是使用 QueryOver。原因:

使用 NH-Linq 的查询可能无法按预期工作。我记不清了,但它不适用于一些复杂的查询。看来是太年轻了。正如 dlang 在之前的回答中所说,它会产生低效的 SQL。 当您学习 QueryOver 时,调用函数、进行投影、子查询很容易,在我看来比使用 NH-Linq 更容易。 对 NH-Linq 来说是件好事 - 它可以扩展,就像 Fabio Maulo 解释的 here。但是,QueryOver 也有类似的可能,但不像 NH-Linq 那样花哨:)

【讨论】:

以上是关于使用 NHibernate 3.0 QueryOver 或 LINQ 提供程序的权衡的主要内容,如果未能解决你的问题,请参考以下文章

NHibernate 3.0:没有使用QueryOver的FirstOrDefault()?

在 NHibernate 3.0 Linq 中急切加载多个兄弟姐妹和孙辈(堂兄弟?)的良好行为

ORM篇——有关NHibernate查询封装

是否可以直接在 NHibernate 中设置引用的外键?

Nhibernate学习教程-- 第一个NHibernate程序

使用 Fluent NHibernate 和 NHibernate 3 将枚举映射为 Int