C# NHibernate Query<> 与 QueryOver<> 有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15020817/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 13:48:41  来源:igfitidea点击:

What is the difference between NHibernate Query<> vs QueryOver<>?

c#nhibernate

提问by Rev1.0

I just started with NHibernate (using SQLite) in my current project and I mostly used Query<>, because I was familiar writing db queries in Linq.

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

When I was confronted with some more complex queries, I did some research on QueryOver<>and figured that it should be favored over Query<>because "QueryOver syntax is NH specific". Also, there seems to be nothing that Query<>can do that QueryOver<>can't accomplish.

当我遇到一些更复杂的查询时,我做了一些研究QueryOver<>并认为它应该受到青睐,Query<>因为“QueryOver 语法是 NH 特定的”。此外,似乎没有什么是Query<>做不到的QueryOver<>

So I began replacing all usages of Query<>accordingly. It wasn't long before I had the first "issue" where using Query<>seemed just more convenient. Example (select highest value from column CustomNumberin table BillingDataEntity):

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

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

What I dislike is the need to explicitly cast the result to int and that the the Query<> version is just easier to read. Am i getting the query totally wrong, or in other words: Is there a better way to do it?

我不喜欢的是需要将结果显式转换为 int 并且 Query<> 版本更易于阅读。我的查询是否完全错误,或者换句话说:有更好的方法吗?

I took a look at the generated SQL output:

我查看了生成的 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)]

What exactly am i looking at? Is this the "internal" (method dependent) query that NHibernate further translates into the actual database query?

我到底在看什么?这是 NHibernate 进一步转换为实际数据库查询的“内部”(方法相关)查询吗?

采纳答案by Rippo

There are plenty of answers regarding QueryOver versus Query here on Stackoverflow but in a nutshell:-

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

QueryOver is a strongly-typed version of Criteria, and is more NHibernate specific. Pretty much anything you can do in ICriteria can be done with QueryOver. In the golden days of ICriteria NH2 you always had to cast, hence this is why now you need to cast at the end of the chain back to an int.

LINQ (Query) is a standard query method that works on IQueryable that doesn't need explicit references to NHibernate and can be considered more ORM agnostic and therefore follows the linq standard. As you rightly pointed out you do not need to cast to an int as you are selecting into the result the customNumber.

QueryOver 是 Criteria 的强类型版本,并且更特定于 NHibernate。您在 ICriteria 中可以做的几乎任何事情都可以使用 QueryOver 来完成。在 ICriteria NH2 的黄金时代,您总是必须进行转换,因此这就是为什么现在您需要在链的末端将转换回 int 的原因。

LINQ (Query) 是一种适用于 IQueryable 的标准查询方法,它不需要显式引用 NHibernate 并且可以被认为是更多的 ORM 不可知论者,因此遵循 linq 标准。正如您正确指出的那样,当您在结果中选择 customNumber 时,您不需要强制转换为 int。

I would be very surprised for your simple example if the generated SQL was very different.

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

I was a big fan of QueryOverbut as the Linq provider is getting more mature then 95% of my queries I use Querybut for some Nhibernate specific stuff I resort back down to QueryOver. Either way I recommend using a profiling tool to see what you can live with.

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

Refs: Tradeoffsor versusand versus

参考文献:权衡

回答by jbl

About your QueryOver version, I would have written :

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

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

It seems quite readable, and the resulting SQL would be something like :

它看起来很有可读性,生成的 SQL 将类似于:

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

Hope this will help

希望这会有所帮助