2015-03-02 57 views
1

此代碼會導致NotSupportedException。爲什麼我們需要使用AsEnumerable()方法?

var detailList = context.Details.Where(x => x.GetType().GetProperty("Code").GetValue(x,null).ToString() == "00101").ToList(); 

但是這段代碼有效。

var detailList = context.Details.AsEnumerable().Where(x => x.GetType().GetProperty("Code").GetValue(x,null).ToString() == "00101").ToList(); 

MSDN說:

- AsEnumerable() Returns the input typed as IEnumerable

- DbSet Is an IEnumerable

那麼,爲什麼我們需要使用AsEnumerable()方法?

+1

爲什麼在使用'var detailList = context.Details.Where(x => x.Code.ToString()==「00101」)時使用了反射。 – 2015-03-02 14:51:57

回答

7

DbSet也是IQueryable

IQueryable擁有自己的一套LINQ擴展方法,可將表達式樹轉換爲SQL,並且不支持反射。

通過調用AsEnumerable(),您將表達式的編譯時類型更改爲IEnumerable<T>,強制擴展方法綁定到標準LINQ。

如果您希望在服務器上運行查詢,則應該構建表達式樹而不是使用反射。

+0

你的解釋不是很理解(很多條款),但我喜歡它(+1)。新東西不是標準答案。 – 2015-03-02 15:01:48

3

第一個查詢嘗試讓查詢提供程序將查詢轉換爲SQL並對數據庫執行查詢。它無法創建有效的數據庫查詢,因此它會因提到的錯誤而失敗。

使用AsEnumerable類型查詢作爲IEnumerable<T>,而不是IQueryable<T>,靜態的,因此結束調用的LINQ對象版本的查詢方法,拉動整個表裝入存儲器中,然後進行內的所有的操作的應用程序。

0

當您查詢IQueryable<T>時,您的方法將通過Expression Tree轉換爲SQL。 AsEnumerable將編譯時間類型更改爲IEnumerable<T>,並將數據庫中的所有實體存入內存,您可以通過LINQ to Objects通過反射查詢它們。

相關問題