2016-04-15 85 views
1

我隔壁班的結構:組合兩個lambda表達式與內表達

public class Order 
    { 
     public User User { get; set; } 
     public string Name { get; set; } 
    } 

    public class Authentication 
    { 
     public string Email { get; set; }  
    } 

    public class User 
    { 
     public string Name { get; set; } 
     public List<Authentication> Auths { get; set; } 
    } 

我想在運行時建立一個表達User.Name,Order.Name或User.Auths搜索實體。電子郵件

有三個表達式我試圖結合:

Expression<Func<Order, bool>> usernameExpression = order => order.Name.Contains(searchValue); 
    Expression<Func<Order, bool>> nameExpression = order => order.User.Name.Contains(searchValue); 
    Expression<Func<Order, bool>> emailExpression = order => order.User.Auths.Any(auth => auth.Email.Contains(searchValue)); 

我成功地結合使用ParameterReplacer從這個線程兩個第一表達式:How to Combine two lambdas

但是,結合產生的電子郵件中表達的表達時,我得到了一個錯誤:

Property 'System.String Email' is not defined for type Order' 

貌似範圍並不知道內部「權威性」參數什麼。 是否有可能在沒有從頭開始重建它的情況下爬行表達式?

+0

在組合中發佈您的嘗試 – CathalMF

+0

你說你想要結合,但*你*要結合他們嗎?你想表達什麼樣的表情? – Servy

+0

@Servy,我試圖用OrAlso \ AndAlso子句將它們結合起來。從Ivan的帖子到幫手的鏈接解決了問題 – Refraction

回答

3

您使用的ParameterReplacer過於簡化,並且每參數都盲目取代

使用這個代替:

public static class ExpressionUtils 
{ 
    public static Expression ReplaceParameter(this Expression expression, ParameterExpression source, Expression target) 
    { 
     return new ParameterReplacer { Source = source, Target = target }.Visit(expression); 
    } 

    class ParameterReplacer : ExpressionVisitor 
    { 
     public ParameterExpression Source; 
     public Expression Target; 
     protected override Expression VisitParameter(ParameterExpression node) 
     { 
      return node == Source ? Target : base.VisitParameter(node); 
     } 
    } 
} 

或者使用thisthis謂詞建設者幫手。

+0

從第一個鏈接表達式助手完全解決了這個問題。謝謝 – Refraction