2013-02-12 56 views
14

我在.NET上有點新鮮,我想知道linq是如何工作的,因爲你可以一個接一個地應用許多linq查詢,但是它們都不會真正執行,直到它們被用來傳輸信息或轉換爲列表等。
有兩種重要的方法可以通過使用IQueryable<T>來獲得linq查詢,這些查詢直接在Sql上進行篩選,IEnumerable可以獲取所有記錄,然後在內存中與它們一起使用。然而,讓我們對這個代碼來看看:將IQueryable linq查詢轉換爲IEnumerable <T>取消了linq優化的工作方式?

  //Linq dynamic library 
      IQueryable<Table> myResult = db.Categories 
       .Where(a => a.Name.Contains(StringName)) 
       .OrderBy("Name") 
       .Skip(0) 
       .Take(10); 

      if (myResult != null) 
      { 
       return myResult.AsEnumerable(); 
      } 
      else 
      { return null; } 

Depsite我使用LINQ的動態庫,從這個查詢的直接結果是在IQueryable<T> GET,如果查詢終於被返回IEnumerable,是查詢是真正過濾的SQL?或者它在內存中?

+1

回答這個問題的最好方法是查看數據上下文的'Log'屬性並親自查看。試驗你的查詢的不同變化,看看它是如何影響*實際執行的。 – Servy 2013-02-12 21:33:43

+0

對不起,我如何檢查日誌? – 2013-02-12 21:34:52

+1

那麼,這可能是一個很好的問題,谷歌或該屬性的MSDN文檔;如果內存服務,那裏就有一個很好的例子。 – Servy 2013-02-12 21:35:54

回答

28

它仍然會在數據庫中執行,不用擔心。基本上全部是使用Where等的實現。當您通過IQueryable<T>調用方法時 - 通過Queryable擴展方法 - 它將使用表達式樹。當您從該查詢開始提取時,它將轉換爲SQL併發送到數據庫。

在另一方面,如果你使用任何這些方法你有它作爲一個IEnumerable<T>(在編譯時類型而言),將使用擴展方法在Enumerable,和所有的其餘的處理在過程中完成。

舉個例子,考慮一下:

var query = db.People 
       .Where(x => x.Name.StartsWith("J")) 
       .AsEnumerable() 
       .Where(x => x.Age > 20); 

這裏AsEnumerable()只是返回其輸入序列,但類型爲IEnumerable<T>。在這種情況下,數據庫查詢將只返回名稱以J開頭的人 - 然後年齡過濾將在客戶端完成。

+1

非常感謝您的回答!他們幫了很多! – 2013-02-12 21:49:03

4

如果你返回一個IEnumerable<T>然後進一步細化查詢,那麼進一步的細化發生在內存中。在IQueryable<T>上表達的部分將被轉換爲適當的SQL語句(對於LINQ-to-SQL的情況,顯然)。

請參閱Returning IEnumerable<T> vs. IQueryable<T>瞭解更長和更詳細的答案。