2016-04-15 11 views
1

Kombinieren habe ich die Struktur nächste Klasse: zur Suche Einheiten von User.Name, Order.Name oder User.Authszwei Lambda-Ausdrücke mit inneren Ausdruck

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; } 
    } 

Ich versuche, einen Ausdruck zur Laufzeit zu bauen. Email

Es gibt drei Ausdrücke, die ich zu kombinieren bin versucht:

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)); 

ich zwei ersten Ausdrücke erfolgreich kombiniert aus diesem Thread mit ParameterReplacer: How to Combine two lambdas

Wenn jedoch resultierenden Ausdruck mit E-Mail-Ausdruck kombiniert bekomme ich die nächsten Fehler:

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

Sehen aus wie der Umfang etwas nicht weiß, über innere ‚Auth‘ Parameter. Ist es möglich, den Ausdruck zu kreuzen, ohne ihn von Grund auf neu aufzubauen?

+0

Posten Sie Ihren Versuch auf die Kombination – CathalMF

+0

Sie sagen, dass Sie die kombinieren möchten, aber * wie * wollen Sie sie kombinieren? Mit welchem ​​Ausdruck willst du enden? – Servy

+0

@Servy, ich habe versucht, sie mit OrAlso \ AndAlso-Klausel zu kombinieren. Der Link zu dem Helfer aus Ivans Beitrag löste das Problem – Refraction

Antwort

3

Der ParameterReplacer, den Sie verwendet haben, ist zu vereinfacht und ersetzt blind alle Parameter.

Verwenden Sie stattdessen:

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); 
     } 
    } 
} 

Oder this oder this Prädikat Bauer Helfer verwenden.

+0

Ausdruck Helfer von der ersten Verbindung perfekt das Problem behoben. Vielen Dank – Refraction

Verwandte Themen