NHibernate Query 与QueryOver 有什么区别?

我刚开始使用NHibernate(使用SQLite)在我当前的项目中,我主要使用Query ,因为我很熟悉在Linq中编写数据库查询。

当我遇到一些更复杂的查询时,我对QueryOver进行了一些研究,并认为它应该优于Query因为“QueryOver语法是NH特定的” 。 此外, Query似乎没有任何QueryOver无法完成的操作。

所以我开始相应地更换Query所有用法。 不久之后,我遇到第一个“问题”,使用Query似乎更方便。 示例(从表BillingDataEntity CustomNumber列中选择最高值):

 int result = Session.Query().Select(x => x.CustomNumber).OrderByDescending(a => a).FirstOrDefault(); int result = Session.QueryOver().Select(x => x.CustomNumber).OrderBy(a => a.CustomNumber).Desc.Take(1).SingleOrDefault(); 

我不喜欢的是需要将结果显式地转换为int,并且Query 版本更容易阅读。 我的查询完全错了,换句话说:有没有更好的方法呢?

我看了一下生成的SQL输出:

 NHibernate: select billingdat0_.CustomNumber as col_0_0_ from "BillingDataEntity" billingdat0_ order by billingdat0_.CustomNumber desc limit 1 NHibernate: SELECT this_.CustomNumber as y0_ FROM "BillingDataEntity" this_ ORDER BY this_.CustomNumber desc limit @p0;@p0 = 1 [Type: Int32 (0)] 

我究竟在看什么? 这是NHibernate进一步转换为实际数据库查询的“内部”(依赖于方法)查询吗?

在Stackoverflow上有很多关于QueryOver与Query的答案,但简而言之: –

QueryOver是Criteria的强类型版本,更具体的NHibernate。 您可以使用QueryOver完成ICriteria中的任何操作。 在ICriteria NH2的黄金时代你总是需要施放,因此这就是为什么现在你需要在链的末端投射回到int。

LINQ(Query)是一种标准查询方法,适用于IQueryable,不需要显式引用NHibernate,因此可以认为它更符合ORM,因此遵循linq标准。 正如您正确指出的那样,当您选择customNumber时,不需要转换为int。

如果生成的SQL非常不同,我会对您的简单示例感到非常惊讶。

我是QueryOver忠实粉丝,但随着Linq提供商变得越来越成熟,95%的查询我都使用Query但是对于一些Nhibernate特定的东西我退回到QueryOver 。 无论哪种方式,我建议使用分析工具来查看您可以使用的内容。

参考: 权衡或与 对比

关于你的QueryOver版本,我会写:

 int result = Session.QueryOver() .Select(Projections.Max(x => x.CustomNumber)) .SingleOrDefault(); 

它似乎很可读,结果SQL将是这样的:

 SELECT max(this_.CustomNumber) as y0_ FROM "BillingDataEntity" this_ 

希望这会有所帮助