如何使用 DISTINCT 在 NHibernate SQL 查询中进行分页
Posted
技术标签:
【中文标题】如何使用 DISTINCT 在 NHibernate SQL 查询中进行分页【英文标题】:How to do pagination in an NHibernate SQL query with DISTINCT 【发布时间】:2011-07-24 04:01:49 【问题描述】:我有一个大而复杂的 SQL 查询,其中包含在 NHibernate 中运行的 DISTINCT 子句(这是一个具有多种条件和连接的搜索查询)。但我在 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
....
由于查询的工作方式,我无法避免重复的行,因此我在 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
这适用于第一页,但在后续页面上我只能得到预期结果的一半。
我在 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
....
当 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
我的问题是:我如何从 NHibernate 而不是我的手动解决方法中做到这一点?
我使用的是 NHibernate 2.1.2 版。
很遗憾,我无法将此查询转换为 HQL 或 LINQ(除非有人可以为我提供几周的空闲时间!)。我也不能从我的查询中删除 DISTINCT。
【问题讨论】:
看起来您的解决方案几乎是唯一的方法。 julianjelfs.wordpress.com/2009/04/03/… @Vadim - 我担心会是这样。您能否将您的评论作为答案,我会将其标记为已接受。 【参考方案1】:对于遇到此问题的其他任何人,似乎它已在 3.3.1 中修复 见https://nhibernate.jira.com/browse/NH-2214
【讨论】:
以上是关于如何使用 DISTINCT 在 NHibernate SQL 查询中进行分页的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 DISTINCT 在 NHibernate SQL 查询中进行分页
如何在 SQL Server 中使用带有框架的窗口函数执行 COUNT(DISTINCT)