2012-01-04 48 views
2

這是一個後續的問題,我問早些時候在這裏看到:是否有一些Funcs不可能轉換爲相應的表達式?

Confused about passing Expression vs. Func arguments

接受的回答者也表明重構的表達式中引用的局部對象到的東西,LINQ到實體能夠實際執行對後備存儲(在我的情況下SQL Server)

我花了很長時間試圖想出一些東西,將爲我正在做的工作。我原來

Func<Thing, bool> whereClause 

被引用當地字典對象,LINQ到實體或SQL會在運行時不會明白。我試圖重構成多個列表僞造字典,然後陣列。每次,我得到運行時錯誤,抱怨上下文無法識別列表上的方法或數組索引器。

最終我放棄了,只是提供了一個額外的方法,當我不能拿出正確的表達式時,需要一個Func參數。

我不是試圖找到一個解決我的具體的問題,我只是在一般的想知道,如果它是總是可能轉換,說

Func<Thing, bool> 

爲等效

Expression<Func<Thing, bool>> 

它可以運行Linq到實體。 或者如果有很多查詢的例子,你只需要必須將數據先拉到內存中。

回答

7

你不轉換Func到表達式樹 - 編譯一個lambda表達式轉換爲表達式樹......不,這並不總是可能的。例如,你可以不聲明拉姆達轉換爲表達式樹:

Expression<Func<string, int>> valid = text => text.Length; 

Expression<Func<string, int>> invalid = text => { return text.Length; }; 

還有其他各種限制,太。

即使你可以創建一個表達式樹(如果你做手工,你可以建立那些其C#編譯器不會,特別是在.NET 4中),這不是一回事爲代表的東西表達式樹LINQ to SQL(等)可以適當地翻譯。

5

喬恩當然是正確的;你將一個lambda轉換爲一個表達式樹。

爲了擴展他的「各種其他限制」 handwave比特:一個lambda轉換爲表達式樹可以不包含:

  • 語句主要是由於它們的狀態的突變
  • 表達式有用:分配,化合物分配,遞增和遞減運算
  • 任何種動態操作
  • 多維數組初始化
  • 除去部分的方法
  • 基訪問
  • 任何種指針操作
  • 的sizeof(T),除了其中T是一個內置型
  • COM式索引屬性調用
  • COM式「可選REF」調用
  • C樣式可變參數的方法調用
  • 可選參數的和命名參數調用
  • 方法羣組(在調用時當然除)

這不是一個詳盡的清單;還有一些怪異的角落案例。但是這應該涵蓋其中的大部分。

+0

謝謝埃裏克。這些只是語言本身提供的限制,是正確的?含義你可以滿足所有這些條件,但仍然讓Linq to SQL無法翻譯它? – Erix 2012-01-04 20:07:43

+1

@Erix:正確。我不知道LINQ to SQL有什麼限制。 – 2012-01-04 20:28:47

相關問題