Как сделать нумерацию страниц в запросе NHibernate SQL с помощью DISTINCT - PullRequest
5 голосов
/ 28 марта 2011

У меня большой и сложный SQL-запрос с предложением DISTINCT, который запускается в NHibernate (это поисковый запрос с широким спектром критериев и объединений).Но у меня проблема с использованием нумерации страниц в SQL Server 2008.

Мой вопрос: как мне сделать это с помощью NHibernate, а не мой обходной мануал (обрисован в общих чертах ниже)?

код, который я использую, это:

 var searchQuery = BuildQuery(criteria);
     .SetTimeout(240)
     .SetFirstResult(pageIndex * pageSize)
     .SetMaxResults(pageSize);
 var resultRows = searchQuery.List<object[]>();

Результаты моего SQL-запроса (из BuildQuery (), без DISTINCT) выглядят так (очень упрощенно):

Id, Name, SortColumn
1   AA    1/1/2000
1   AA    1/1/2000
2   AB    3/1/2000
2   AB    3/1/2000
3   AC    10/1/2000
3   AC    10/1/2000
....

Iя не могу избежать повторяющихся строк из-за того, как работает запрос, поэтому я вставляю DISTINCT в запрос SQL, чтобы заставить их исчезнуть.

Чтобы выполнить нумерацию страниц, NHibernate генерирует запрос, подобный этому (этот примерсо второй страницы (100 результатов на странице):

SELECT   TOP 100 Id,
             Name,
             SortColumn,
FROM     (select distinct Id, Name, SortColumn,
                 ROW_NUMBER() OVER (ORDER BY SortColumn) as __hibernate_sort_row
          from ......
          where ......) as query
WHERE    query.__hibernate_sort_row > 100
ORDER BY query.__hibernate_sort_row

Это нормально для первой страницы, но на последующих страницах я получаю только половину ожидаемых результатов.

Я запускаю SQLв подзапросе NHibernate и обнаружил, что строка, которую NHibernate вставляет для выполнения нумерации страниц, возвращает что-то неожиданное (даже с DISTINCT):

Id, Name, SortColumn,     __hibernate_sort_row
1   AA    1/1/2000,       1
1   AA    1/1/2000,       2
2   AB    3/1/2000,       3
2   AB    3/1/2000,       4
3   AC    10/1/2000,      5
3   AC    10/1/2000,      6
....

Когда NHibernate переносит это в подзапрос для фильтрации в __hibernaСтолбец te_sort_row возвращает 100 строк, но поскольку каждая строка дублируется, на моей странице действительно только 50 строк.Это потому, что DISTINCT не объединяет строки, как я ожидал.(Все это восходит к тому, как функция ROW_NUMBER () работает в SQL 2008 с предложением DISTINCT, но это проблема NHibernate, а не моя.).

В настоящее время я решил эту проблему, заключив запрос в дваподзапросы и ручная обработка нумерации страниц:

SELECT TOP 100 paginationOuter.*
FROM
(
SELECT paginationInner.*
    ,ROW_NUMBER() OVER(ORDER BY SortColumn ASC) AS RowNum
FROM
    (
            select distinct Id, Name, SortColumn,
            from ......
            where ......
    ) AS paginationInner
) AS paginationOuter
WHERE    paginationOuter.RowNum > 100
ORDER BY paginationOuter.RowNum

Мой вопрос: как мне сделать это из NHibernate, а не мой ручной обход?

Я использую NHibernate версии 2.1.2.

К сожалению, я не могу преобразовать этот запрос в HQL или LINQ (если кто-то не может предоставить мне несколько недель свободного времени!).Также я не могу удалить DISTINCT из моего запроса.

1 Ответ

0 голосов
/ 01 августа 2012

Для всех, кто сталкивается с этой проблемой, похоже, что она исправлена ​​в 3.3.1 См. https://nhibernate.jira.com/browse/NH-2214

...