NHibernate HQL SELECT TOP в подзапросе - PullRequest
5 голосов
/ 12 января 2010

Есть ли способ использования SetMaxResult () для подзапроса? Я пишу запрос, чтобы вернуть все элементы заказа, относящиеся к самому последнему заказу. Поэтому мне нужно ограничить количество записей в подзапросе.

Эквивалентный sql выглядит примерно так:

SELECT i.*
FROM tbl_Orders o
JOIN tbl_OrderItems i on i.OrderId = o.Id
WHERE
o.Id in (SELECT TOP 1 o.Id FROM tbl_Orders o orderby o.Date desc)

Я использую hql специально, потому что критерии api не позволяют вам проецировать другой объект домена (я запрашиваю заказы, но хочу вернуть позиции заказа)

Я знаю, что hql не принимает "SELECT TOP", но если я использую SetMaxResult (), он будет применяться к внешнему запросу, а не к подзапросу.

Есть идеи?

Ответы [ 3 ]

3 голосов
/ 09 апреля 2015

В NHibernate 3.2 вы можете использовать SKIP n / TAKE n в hql в конце запроса. Ваш запрос будет:

SELECT i.*
FROM tbl_Orders o
JOIN tbl_OrderItems i on i.OrderId = o.Id
WHERE
o.Id in (SELECT o.Id FROM tbl_Orders o orderby o.Date desc take 1)
3 голосов
/ 12 января 2010

Просто запросите заказы (и используйте SetMaxResult) и выполните «выборочное объединение», чтобы сразу загрузить все элементы заказов для выбранных заказов. На возвращенных заказах вы можете получить доступ к элементам заказа без этого, что приведет к отправке нового оператора SQL в базу данных.

1 голос
/ 03 февраля 2012

Я тоже сталкивался с этой проблемой, но не нашел решения с использованием HQL ...

Подзапросы с top были бы очень хорошими, так как это быстрее, чем сначала делать полное объединение. При первом полном объединении SQL-серверы сначала присоединяются к таблице, сортируют все строки и затем выбирают верхние 30. С помощью подвыбора, верхний 30 столбец одной таблицы берется, а затем соединяется с другой таблицей. Это намного быстрее!

Мой запрос с помощью Subselect занимает около 1 секунды, запрос с объединением и сортировкой занимает 15 секунд! Так что присоединиться не было возможности.

В итоге у меня возникло два запроса, первый из которых был выбран:

IQuery q1 = session.CreateQuery("select id from table1 order by id desc");
q1.SetMaxResults(100);

А потом второй запрос

IQuery q2 = session.CreateQuery("select colone, coltwo from table2 where table1id in (:subselect)");
q2.SetParameterList("subselect", q1.List());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...