2012-09-03 22 views
3

比方說,我有兩個參數:C#表達式容易地轉換與==或等於運算和外部參數

參數1,需要一個T和從它

Expression<Func<T,int>> prodIdProperty = x=>x.Product.Id 

獲取相關聯的產品的ID的表達參數2的productid與比較,讓我們說

int productid = 5; 

有什麼辦法,我可以運行時改變這個(代碼)進入這樣一個新的表達:

Expression<Func<T,bool>> prodIdProperty = x=>x.Product.Id == 5 

基本上,我需要這樣的:

Expression<Func<T,bool>> TransformToPredicate(Expression<Func<T,int>> prodIdProperty,int productid){ 
//insert expression transform magic I don't seem to grasp... 
} 

,因爲我希望把它作爲一個謂語我EF Where子句我需要這個,這意味着我可以不包括我prodIdProperty的編譯版本爲它需要調用的invoke()至極,不支持

(我已經嘗試制定我的問題的另一種方式this的問題,但我認爲我過於複雜那兒)

回答

9

這聽起來像你想要的東西,如:

Expression<Func<T, bool>> TransformToPredicate(
    Expression<Func<T, int>> prodIdProperty, 
    int productId) 
{ 
    Expression equals = Expression.Equal(prodIdProperty.Body, 
             Expression.Constant(productId)); 
    return Expression.Lambda<Func<T, bool>>(equals, prodIdProperty.Parameters); 
} 

示例代碼顯示在用行動表明:

using System; 
using System.Linq.Expressions; 

class Test 
{  
    static Expression<Func<T, bool>> TransformToPredicate<T>(
     Expression<Func<T, int>> prodIdProperty, 
     int productId) 
    { 
     Expression equals = Expression.Equal(prodIdProperty.Body, 
              Expression.Constant(productId)); 
     return Expression.Lambda<Func<T, bool>>(equals, prodIdProperty.Parameters); 
    } 

    static void Main() 
    { 
     Expression<Func<string, int>> length = x => x.Length; 

     var predicate = TransformToPredicate(length, 5); 
     var compiled = predicate.Compile(); 

     Console.WriteLine(compiled("Hello")); // True 
     Console.WriteLine(compiled("Foo")); // False 
    } 
} 
+0

起初看起來很棒,但是這並不適合我工作尚未.. Expression.Equals回報一個布爾型不是表達式,Expression.Equal(無s)我認爲你的意思是,讓我編譯,但拋出一個運行時表達式,因爲它無法比較二進制表達式到一個int –

+0

是否有一個Equals重載或擴展方法im遺漏在基本的Expressions命名空間中? –

+0

@Mvision:對不起,我的意思是'Expression.Equal',是的。至於比較失敗,應該沒問題......你正在比較「代表屬性訪問的表達式」和「代表常量的表達式」。將看看我是否可以測試它,然後在必要時修復它... –