c# - Combine two linq expressions to inject navigation property -


i have identical set of conditions applied 1 class directly or other class having same navigation property.

for example, have home , have agent, agent associated home.

so looking home agency name 'a', or looking agent name 'a', queries follow,

 expression<<func<agent,bool>> ax = x=> x.name == "a" ;   expression<func<home,bool>> hx = x=> x.agent.name == "a"; 

i have 100 search queries agent, , have apply them home queryable well. dont mind writing again, difficult maintain know change during course of development.

what want is, want compose expression home query this,

 expression<func<home,bool>> hx = combine( x=>x.agent , x=>x.name == "a"); 

where combine following,

 expression<func<t,bool>> combine<t,tnav>(       expression<func<t,tnav>> parent,       expression<func<tnav,bool>> nav){       // combine above form...        (x=>x.agent , x=>x.name == "a")           => x => x.agent.name == "a"       (x=>x.agent, x=>x.name.startswith("a") || x.name.endswith("a"))          => x=>x.agent.name.startswith("a") || x.agent.name.endswith("a")       // carefully, x gets replaced x.agent in every node..       // know little expression rewriting, need little  } 

yes, need visitor replace parts of original expressions. that:

expression<func<t,bool>> combine<t,tnav>(expression<func<t,tnav>> parent, expression<func<tnav,bool>> nav) {      var param = expression.parameter(typeof(t), "x");      var visitor = new replacementvisitor(parent.parameters[0], param);      var newparentbody = visitor.visit(parent.body);      visitor = new replacementvisitor(nav.parameters[0], newparentbody);      var body = visitor.visit(nav.body);      return expression.lambda<func<t, bool>>(body, param); }  public class replacementvisitor : system.linq.expressions.expressionvisitor {     private readonly expression _oldexpr;     private readonly expression _newexpr;     public replacementvisitor(expression oldexpr, expression newexpr)     {         _oldexpr = oldexpr;         _newexpr = newexpr;     }      public override expression visit(expression node)     {         if (node == _oldexpr)             return _newexpr;         return base.visit(node);     }  } 

example usage:

expression<func<foo, bar>> expr1 = f => f.bar; expression<func<bar, bool>> expr2 = b => b.baz; var expr = combine(expr1, expr2); // f => f.bar.baz 

Comments

Popular posts from this blog

java - Play! framework 2.0: How to display multiple image? -

gmail - Is there any documentation for read-only access to the Google Contacts API? -

php - Controller/JToolBar not working in Joomla 2.5 -