2011-04-20 48 views
2

標準查詢運算符對Linq to Object序列進行操作,該序列實現IEnumerable<T>接口,而Linq to Sql運算符則調用接口類型爲IQueryable<T>的序列。因此,標準查詢操作不能得到所謂的IQueryable<T>類型的順序,除非該順序是先投給IEnumerable<T>(通過AsEnumerable運營商)爲什麼我們不能在IQueryable類型的序列上調用標準查詢操作符<T>?

一)爲什麼不能標準查詢操作沒有LINQ到SQL副本(如Reverse()),在IQueryable<T>序列上被調用?即,IQueryable<T>源自IEnumerable<T>,因此擴展類實現IEnumerable<T>的擴展方法也應該擴展實現從IEnumerable<T>派生的接口的類。

二)不管怎麼說,這爲什麼會是一個壞主意,能夠這樣的順序來調用標準查詢運算符(那些沒有LINQ到SQL副本)上IQueryable<T>類型的序列,而無需首先鑄造IEnumerable<T>(通過AsEnumerable運營商)?

感謝名單

回答

3

一般IQueryable<T>不只是從Linq到SQL,任何查詢提供者都可以選擇使用有限的一組操作來支持這種約定 - 並非所有查詢提供者都支持相同的子集。

支持的子集取決於在查詢提供程序的域中有意義的內容。 IQueryable<T>在表達式樹上運行,允許查詢提供者將查詢轉換爲底層數據源(即SQL)的領域特定語言。

+1

我記得在不久之前被問到類似這樣的事情。 BrokenGlass具有相當的震撼力。考慮IQueryable 作爲表達式,函數或函數列表。 IEnumerable是內存中的結果 - 無論它們是從IQueryable還是以其他方式派生。一旦你理解了這一點,你就會明白爲什麼IEnumerable的函數在IQueryable上不起作用。 +1到BrokenGlass – Smudge202 2011-04-20 19:32:43

+0

我必須承認,我對錶情樹一無所知。無論如何,從C#語法規則的角度來看,調用IQueryable .Reverse應該可以工作,正如我在初始文章中所解釋的那樣。我很好奇爲什麼C#規則不適用於此? – flockofcode 2011-04-20 21:40:13

+1

@flockofcode:它們的確適用 - 這不會產生*編譯時錯誤*(因爲擴展方法是爲'IQuerable '定義的,但是*運行時錯誤*如果不被支持(例如,如果沒有等價的域,查詢提供程序正在映射到的域)對於Linq to SQL,例如嘗試使用TakeWhile,SkipWhile,Reverse,Last,LastOrDefault等時會發生異常 - 完整列表http: //msdn.microsoft.com/en-us/library/bb399342.aspx – BrokenGlass 2011-04-20 22:12:23

1

如果我理解正確你的問題的LINQ to SQL查詢產生的SQL查詢,因爲LINQ to SQL是不同的LINQ提供程序,IEnumerable的用於內存中集合的查詢

相關問題