我有一個很大且複雜的SQL查詢,它帶有一個在NHibernate中運行的DISTINCT子句(這是一個包含各種條件和連接的搜索查詢)。但我在使用SQL Server 2008中的分頁時遇到問題。如何使用DISTINCT在NHibernate SQL查詢中執行分頁
我的問題是:我如何從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
也能正常工作的第一頁,但在隨後的頁面我只獲得預期成果的一半。
我運行SQL NHibernate的子查詢中,發現NHibernate的插入做它的分頁行返回意想不到的事情(即使是不同的):
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沒有像我期望的那樣合併行。 (所有這些都回到了SQL 2008中ROW_NUMBER()函數如何在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。
看起來像你的解決方案是非常做到這一點的唯一途徑。 http://julianjelfs.wordpress.com/2009/04/03/nhibernate-removing-duplicates-combined-with-paging/ – Vadim 2011-03-28 15:26:29
@Vadim - 我擔心會是這樣。你可以把你的評論作爲答案,我會將其標記爲已接受。 – ligos 2011-03-28 21:59:38