2011-06-08 20 views
1

我正在學習Linq-to-Sql,我遇到了我試圖建立一個動態查詢與排序,過濾和分頁。根據方法是否鏈接在一起的不同Linq到SQL結果

如果我運行一個查詢這樣我能夠得到「分頁」的結果:

IQueryable<WorkOrder> query = (_dataContext.WorkOrders).Skip((search.page - 1) * search.rows).Take(search.rows); 
var retval = query.ToList(); 

在這種情況下,生成的查詢看起來是這樣的:

SELECT <columns> 
FROM (
    SELECT ROW_NUMBER() OVER (<columns>) AS [ROW_NUMBER], <columns> 
    FROM [dbo].[WorkOrders] AS [t0] 
    ) AS [t1] 
WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p0 + @p1 
ORDER BY [t1].[ROW_NUMBER] 

但是,如果我運行像這樣的查詢,它不再被分頁:

IQueryable<WorkOrder> query = (_dataContext.WorkOrders); 
query.Skip((search.page - 1) * search.rows).Take(search.rows); 
var retval = query.ToList(); 

在這種情況下,生成的查詢如下所示:

SELECT <cut for brevity> 
FROM [dbo].[WorkOrders] AS [t0] 

我真的不能神交是怎麼回事?這裏究竟什麼時候Sql的Linq生成查詢,並可以添加額外的標準一樣跳過,拿,排序依據,以現有的IQueryable?當我想最終會是這樣的:

IQueryable<WorkOrder> query = (_dataContext.WorkOrders); 
if (User.IsNotAuthorizedToSeeSomething) { 
    query.Where(...); 
} 
if (search.sortField.Equals("Name")) { 
    query.OrderBy(...); 
} 
query.Skip((search.page - 1) * search.rows).Take(search.rows); 
var retval = query.ToList(); 
+0

您是否嘗試過使用SQL Profiler運行的代碼?你能看到SQL實際發送到數據庫的是哪一行嗎?也許這可以幫助回答你的問題。 – 2011-06-08 19:40:18

+0

我使用SQL分析器來檢索上面顯示的生成的查詢;事實證明,問題是我沒有意識到每個Linq方法調用實際上都會返回一個新的IQueryable實例。 – BCG 2011-06-09 11:22:11

回答

4

而不是

IQueryable<WorkOrder> query = (_dataContext.WorkOrders); 
query.Skip((search.page - 1) * search.rows).Take(search.rows); 
var retval = query.ToList(); 

嘗試

IQueryable<WorkOrder> query = (_dataContext.WorkOrders); 
query = query.Skip((search.page - 1) * search.rows).Take(search.rows); 
var retval = query.ToList(); 

每個query.Xxx()查詢對象,但收益上不適用的xxx新對象。

+0

是的,這是至關重要的缺失部分 - 您不會將Skip的結果分配給任何內容,因此它不會修改查詢。 – GalacticCowboy 2011-06-08 19:48:01

+1

對於你的問題的其餘部分,你絕對可以做你想做的事情,你只需要繼續按照與此處顯示的qrow相同的模式。 * query = query.Where(...)*在你的if語句中。 – GalacticCowboy 2011-06-08 19:51:04

+0

好吧,我現在明白了。我想我在想,擴展方法都只是修改相同的IQueryable實例,但它看起來像實際上爲每個方法調用返回一個新的IQueryable。這個答案絕對解決了我的問題。謝謝! – BCG 2011-06-08 19:51:19

-1

看來,在第二種情況下它會提前和對數據庫執行查詢的第一行執行時。然後,Skip和Take按照LINQ to Objects而不是LINQ to SQL的方式執行。

我真的不知道爲什麼它會做,雖然...

做的RETVAL值看起來相同的兩種情況。 (它不應該,如果我認爲是真正發生的事情。)

+0

返回值看起來不一樣......在第二種情況下,我得到生成的查詢結果。 – BCG 2011-06-08 19:48:01

+0

我想我應該仔細看看評論。我只注意到問題是你沒有分配結果。我自己做了好幾次。 – 2011-06-08 20:38:48