2015-02-11 84 views
0

當尋找到實現在C#分頁的最佳方法(使用LINQ),大多數建議是沿着這些路線的東西:高效分頁大型數據集LINQ

// Execute the query 
var query = db.Entity.Where(e => e.Something == something); 

// Get the total num records 
var total = query.Count(); 

// Page the results 
var paged = query.Skip((pageNum - 1) * pageSize).Take(pageSize); 

這似乎是一般建議的策略(簡化)。

對我而言,我在尋呼的主要目的是提高效率。如果我的表格包含120萬個記錄Something ==某些東西,我不想同時檢索所有這些記錄。相反,我想分頁數據,抓取儘可能少的記錄。但用這種方法,似乎這是一個有爭議的問題。

如果我理解正確,第一條語句仍然檢索120萬條記錄,,然後根據需要分頁。

以這種方式進行分頁實際上是否提高了性能?如果每次都要檢索120萬條記錄,那麼除了顯而易見的UI優勢外,還有什麼意義?

我誤解了嗎?任何.NET專家,可以給我一個關於LINQ,分頁和性能的課程(當處理大型數據集時)?

+0

@Mr香港人:使用號'.Select' Linq中不會造成枚舉。 – spender 2015-02-11 01:36:56

回答

6

第一條語句不執行實際的SQL查詢,它只構建您打算運行的查詢的一部分。

它是當你調用query.Count()第一將被執行

SELECT COUNT(*) FROM Table WHERE Something = something 

query.Skip().Take()也不會執行查詢,只有當你嘗試過paged或枚舉結果(做一個foreach調用.ToList()),它將執行適當的SQL語句,僅檢索頁面的行(使用ROW_NUMBER)。

如果在SQL事件探查器中觀察此事件,您將看到正好執行了兩個查詢,並且在任何時候它都將嘗試檢索完整的表。


要小心,當您使用調試器,因爲如果你的第一條語句後退一步,嘗試看看的query內容,將執行SQL查詢。也許這就是你誤解的根源。

+0

謝謝!你關於調試器的提示非常有用 - 調試'query'促使我提出這個問題。感謝你的回答。 – 2015-02-11 02:14:10

2

我相信實體框架可能會基於linq語句使用合適的條件構造SQL查詢。 (例如使用ROWNUMBER()OVER ...)。

但是,我可能是錯的。我會運行SQL分析器並查看生成的查詢的樣子。

3
// Execute the query 
var query = db.Entity.Where(e => e.Something == something); 

爲了您的信息,什麼叫第一個語句之後。

// Get the total num records 
var total = query.Count(); 

這個計數查詢將被轉換爲SQL,它會調用數據庫。 此調用不會得到所有的記錄,因爲生成的SQL是這樣的:

SELECT COUNT(*) FROM Entity where Something LIKE 'something' 

在過去的查詢,它沒有得到所有的記錄既不。查詢將被翻譯成SQL,並且分頁在數據庫中運行。

也許你會發現這個問題非常有用:efficient way to implement paging

+0

謝謝! +1。如果我可以給出2個複選標記,我會的,但是Equiso在他關於調試器的說明中稍微有點幫助。謝謝你的幫助! – 2015-02-11 02:15:21