Wie erstelle ich dynamisch einen Ausdruck & lt; Func & lt; MyClass, bool & gt; & gt; Prädikat von Ausdruck & lt; Func & lt; MyClass, string & gt; & gt;

Ich versuche Anhängen, wo Prädikate und mein Ziel ist, erstellen Sie den gleichen Ausdruck wie:

Services.Where(s => s.Name == "Modules" && s.Namespace == "Namespace");

Ich habe den folgenden code:

Expression<Func<Service,string>> sel1 = s => s.Name;
Expression<Func<Service,string>> sel2 = s => s.Namespace;

var val1 = Expression.Constant("Modules");
var val2 = Expression.Constant("Namespace");

Expression e1 = Expression.Equal(sel1.Body, val1);
Expression e2 = Expression.Equal(sel2.Body, val2);
var andExp = Expression.AndAlso(e1, e2);

ParameterExpression argParam = Expression.Parameter(typeof(string), "s");
var lambda = Expression.Lambda<Func<string, bool>>(andExp, argParam);

Diesem erstellen Sie die folgende Ausgabe:

s => ((s.Name == "Modules") AndAlso (s.Namespace == "Namespace"))

Dies ist jedoch fehlerhaft, da die parameter für Namen und Namespace ist nicht das gleiche. Wenn ich ändern Sie die expression-Auswahl:

Expression<Func<Service,string>> sel2 = srv => srv.Namespace;

Ist die Ausgabe:

s => ((s.Name == "Modules") AndAlso (srv.Namespace == "Namespace"))

Wie kann ich eine gültige expression, die mit der Nutzung von sel1 und sel2?

UPDATE (28 feb 2011)

Ich löste es durch das erstellen invoke-Ausdrücke: Expression.Invoke also die lambda-Ausdrücke sel1 und sel2 nicht erforderlich, um eine MemberExpression:

Expression<Func<Service,string>> sel1 = s => s.Name;
Expression<Func<Service,string>> sel2 = srv => srv.Namespace;

var val1 = Expression.Constant("Modules");
var val2 = Expression.Constant("Namespace");

Expression<Func<Service, bool>> lambda = m => true;
var modelParameter = lambda.Parameters.First();

//sel1 predicate
{
    var invokedExpr = Expression.Invoke(sel1, modelParameter);
    var binaryExpression = Expression.Equal(invokedExpr, val1);
    lambda = Expression.Lambda<Func<Service, bool>>(Expression.AndAlso(binaryExpression, lambda.Body), lambda.Parameters);
}
//sel2 predicate
{
    var invokedExpr = Expression.Invoke(sel2, modelParameter);
    var binaryExpression = Expression.Equal(invokedExpr, val2);
    lambda = Expression.Lambda<Func<Service, bool>>(Expression.AndAlso(binaryExpression, lambda.Body), lambda.Parameters);
}

InformationsquelleAutor der Frage Torbjörn Hansson | 2011-02-23

Schreibe einen Kommentar