c# - How do I dynamically create an Expression<Func<MyClass, bool>> predicate from Expression<Func<MyClass, string>>? -
i trying append predicates , goal create same expression as:
services.where(s => s.name == "modules" && s.namespace == "namespace");
i have following 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);
this create following output:
s => ((s.name == "modules") andalso (s.namespace == "namespace"))
however, faulty since parameter name , namespace isn't same. if change 1 of expression selector to:
expression<func<service,string>> sel2 = srv => srv.namespace;
the output be:
s => ((s.name == "modules") andalso (srv.namespace == "namespace"))
how can create valid expression use of sel1 , sel2?
update (28 feb 2011)
i solved creating invoke expressions: expression.invoke
lambda expressions sel1 , sel2 don't necessary need 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); }
it's hard mix compiler-generated expression trees , hand-made ones, precisely because of sort of thing - extracting out parameterexpressions tricky. let's start scratch:
parameterexpression argparam = expression.parameter(typeof(service), "s"); expression nameproperty = expression.property(argparam, "name"); expression namespaceproperty = expression.property(argparam, "namespace"); var val1 = expression.constant("modules"); var val2 = expression.constant("namespace"); expression e1 = expression.equal(nameproperty, val1); expression e2 = expression.equal(namespaceproperty, val2); var andexp = expression.andalso(e1, e2); var lambda = expression.lambda<func<service, bool>>(andexp, argparam);
one important aspect i've changed type passed expression.parameter
- looks should service
rather string
.
i've given try, , seemed work when called lambda.compile
, executed on couple of sample service
objects...
Comments
Post a Comment