2012-12-07 23 views
5

baut Gibt es eine Möglichkeit, Expression<Func<T,bool>> von Expression<Func<T>> zu bauen?Wie man Ausdruck <Func<T,bool>> von Ausdruck <Func<T>>

Zum Beispiel für die Klasse

public class MyClass 
{ 
    public int Prop1{get;set;} 
    public int Prop2{get;set;} 
    public int Prop3{get;set;} 
} 

wenn Expression<Func<T>> ist () => new MyClass{Prop2 = 5} dann sollte x => x.Prop2 == 5

wenn Expression<Func<T>> ist sein führen () => new MyClass{Prop1 = 1, Prop3 = 3} dann sollte x => x.Prop1 == 1 && x.Prop3 == 3

Mit anderen Worten sein Ergebnis ist es möglich func zu erstellen mit einer beliebigen Anzahl von Bedingungen zur Laufzeit?

+0

Sie dynamische Linq verwenden können: http://weblogs.asp.net/scottgu/archive/2008/01 /07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx –

Antwort

6

So:

static Expression<Func<T,bool>> Munge<T>(Expression<Func<T>> selector) 
{ 
    var memberInit = selector.Body as MemberInitExpression; 
    if (memberInit == null) 
     throw new InvalidOperationException("MemberInitExpression is expected"); 
    var p = Expression.Parameter(typeof(T), "x"); 

    Expression body = null; 
    foreach (MemberAssignment binding in memberInit.Bindings) 
    { 
     var comparer = Expression.Equal(
      Expression.MakeMemberAccess(p, binding.Member), 
      binding.Expression); 
     body = body == null ? comparer : Expression.AndAlso(body, comparer); 
    } 
    if (body == null) body = Expression.Constant(true); 

    return Expression.Lambda<Func<T, bool>>(body, p); 
} 
+0

Das ist perfekt. Vielen Dank. – VladK

2

den Code Lassen Sie uns sprechen für sich:

class Program 
{ 
    static Expression<Func<T, bool>> Transform<T>(Expression<Func<T>> expression) 
    { 
     var initExpression = expression.Body as MemberInitExpression; 
     if (initExpression == null) 
     { 
      throw new ArgumentException(); 
     } 

     Expression bodyExpression = Expression.Constant(true); 
     IEnumerable<MemberBinding> bindings = initExpression.Bindings; 
     ParameterExpression param = Expression.Parameter(typeof(T)); 

     foreach (var memberBinding in bindings) 
     { 
      var memberAssigment = memberBinding as MemberAssignment; 
      if (memberAssigment == null) 
      { 
       throw new ArgumentException(); 
      } 

      var member = memberAssigment.Member; 
      var value = memberAssigment.Expression; 

      bodyExpression = Expression.AndAlso(
       bodyExpression, 
       Expression.Equal(
        Expression.MakeMemberAccess(param, member), 
        value 
       ) 
      ); 
     } 

     return Expression.Lambda<Func<T, bool>>(bodyExpression, param); 
    } 

    static void Main(string[] args) 
    { 
     Expression<Func<MyClass>> exp =() => new MyClass { Prop1 = 1, Prop3 = 3 }; 

     var result = Transform(exp); 
     var lambda = result.Compile(); 

     var array = new[] 
     { 
      new MyClass { Prop1 = 1, Prop3 = 3 }, 
      new MyClass { Prop1 = 1, Prop2 = 2, Prop3 = 3 }, 
      new MyClass { Prop1 = 1, Prop3 = 1 }, 
      new MyClass { Prop1 = 3, Prop3 = 3 }, 
      new MyClass { Prop1 = 3, Prop3 = 1 }, 
      new MyClass() 
     }; 

     foreach (var o in array) 
     { 
      Console.WriteLine(lambda(o)); 
     } 
    } 
} 
Verwandte Themen