2016-06-21 99 views
1

我知道實體框架查詢不能包含數組。例如,這將失敗:爲什麼我們不能在實體框架查詢中使用數組?

var myRow = DbContext.myTable.Single(d => d.Property1 == myArray[0].Property1); 

但是,如果我分配一個元素到一個變量第一這樣的:

var property1 = myArray[0].Property1; 
var myRow = DbContext.myTable.Single(d => d.Property1 == property1); 

然後,它的工作原理。爲什麼編譯器不能爲我們做這件事?它在許多其他情況下已經通過語法糖進行了優化並提供了我們的捷徑。有沒有模糊的來源會阻止編譯器將數組元素複製到後臺的臨時變量中?還是其他原因?

+0

這不是C#編譯器的限制,而是Linq to Entities提供程序。 –

+1

因爲在你的第二段代碼中,你正在使用一個常量值,而這個值又可以是表達式的一部分。第一段代碼中的linq不能轉換爲表達式。 –

+0

關於幾乎每個不會被LINQ-to-EF/LINQ-to-SQL提供程序轉換爲SQL的特定方法/屬性,都有許多類似的(不完全重複的)討論。即http://stackoverflow.com/questions/3360772/linq-contains-case-insensitive與其他討論有很好的聯繫。 –

回答

3

Linq-to-objects可以很好地處理 - 它是linq-to-EF(或Linq-to-SQL),它會嘗試將表達式轉換爲SQL。將值放入變量中告訴提供者您想使用該值,而不是評估表達式。

爲什麼編譯器不能爲我們做這個?

因爲編譯器還沒有被編程來區分應該轉換爲SQL的表達式和在編譯查詢之前應該評估的表達式。

LINQ查詢使用延遲執行,這意味着該查詢實際上不是執行直到你要求的結果。在此之前,它只是一個由構成過濾器,投影,分組,集合等的單個表達式組成的查詢。當它評估表達式d => d.Property1 == myArray[0].Property1時它確實而不是當時評估表達式,所以當提供者得到它時,它會嘗試將其轉換爲SQL,但它無法執行此操作。

+0

而且因爲編譯器無法區分將同步執行的表達式樹(因此可能將索引訪問轉換爲結果)與異步執行(當評估表達式之前,給定索引處的元素可能發生多次更改時)。 –

相關問題