如何使用DISTINCT在NHibernate SQL查询中进行分页

lig*_*gos 5 c# sql nhibernate distinct

我有一个大而复杂的SQL查询,带有一个在NHibernate中运行的DISTINCT子句(它是一个具有各种标准和连接的搜索查询).但是我在使用SQL Server 2008下的分页时遇到了问题.

我的问题是:我如何从NHibernate而不是我的手动解决方法(如下所述)这样做?

我正在使用的代码是这样的:

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

我的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
....
Run Code Online (Sandbox Code Playgroud)

由于查询的工作原理,我无法避免重复的行,所以我在SQL查询中粘贴DISTINCT以使它们消失.

为了进行分页,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
Run Code Online (Sandbox Code Playgroud)

这适用于第一页,但在后续页面上我只得到预期结果的一半.

我在NHibernate的子查询中运行SQL,发现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
....
Run Code Online (Sandbox Code Playgroud)

当NHibernate将它包装在子查询中以过滤__hibernate_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
Run Code Online (Sandbox Code Playgroud)

我的问题是:我如何从NHibernate而不是我的手动解决方法中做到这一点?

我正在使用NHibernate 2.1.2版.

不幸的是,我无法将此查询转换为HQL或LINQ(除非有人可以为我提供几周的空闲时间!).我也无法从查询中删除DISTINCT.

小智 0

对于遇到此问题的其他人,似乎已在 3.3.1 中修复,请参阅https://nhibernate.jira.com/browse/NH-2214