Подтвердить что ты не робот

В чем разница между запросом NHibernate <> vs QueryOver <>?

Я только что начал с NHibernate (используя SQLite) в моем текущем проекте, и я в основном использовал Query<>, потому что мне было знакомо писать db-запросы в Linq.

Когда я столкнулся с некоторыми более сложными запросами, я провел некоторое исследование в QueryOver<> и понял, что он должен быть предпочтительнее Query<>, потому что "синтаксис QueryOver является специфичным для NH". Кроме того, нет ничего, что Query<> может сделать, что QueryOver<> не может выполнить.

Итак, я начал заменять все обычаи 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>();

То, что мне не нравится, - это необходимость явно передать результат в 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 далее переводит в фактический запрос к базе данных?

4b9b3361

Ответ 1

В QueryOver и Query есть много ответов на Stackoverflow, но в двух словах: -

QueryOver - это строго типизированная версия критериев, и это больше NHibernate специфический. Практически все, что вы можете сделать в ICriteria, может выполняться с помощью QueryOver. В золотые дни ICriteria NH2 у вас всегда было чтобы бросить, поэтому именно поэтому вам нужно бросить в конце верните цепочку обратно в int.

LINQ (Query) - это стандартный метод запросов, который работает на IQueryable, что не нуждается в явных ссылках на NHibernate и может быть рассмотрен больше ORM агностик и поэтому следует стандарту linq. Как и ты правильно указал, что вам не нужно бросать в int, поскольку ваши выбрав в результате customNumber.

Я был бы очень удивлен вашим простым примером, если сгенерированный SQL был совсем другим.

Я был большим поклонником QueryOver, но по мере того, как поставщик Linq становится более зрелым, а 95% моих запросов я использую Query, но для некоторых конкретных вещей Nhibernate я возвращаюсь обратно к QueryOver. В любом случае я рекомендую использовать инструмент профилирования, чтобы узнать, с чем вы можете жить.

Refs: Tradeoffs или против и против

Ответ 2

О вашей версии QueryOver я бы написал:

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

Кажется вполне читаемым, и получившийся SQL будет примерно таким:

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

Надеюсь, это поможет