c# - Convert Linq expression "obj => obj.Prop" into "parent => parent.obj.Prop" -


i have existing expression of type expression<func<t, object>>; contains values cust => cust.name.

i have parent class field of type t. need method accepts above parameter , generates new expression takes parent class (tmodel) parameter. used expression parameter of mvc method.

thus, cust => cust.name becomes parent => parent.customer.name.

likewise, cust => cust.address.state becomes parent => parent.customer.address.state.

here's initial version:

    //note: fielddefinition object contains first expression     //described above, plus memberinfo object property/field     //in question     public expression<func<tmodel, object>> expressionfromfield<tmodel>(fielddefinition<t> field)         tmodel: basemodel<t>     {         var param = expression.parameter(typeof(tmodel), "t");          //note in next line "nameof(selecteditem)". reference         //to property in tmodel contains instance         //to retrieve value. unqualified because method         //resides within tmodel.         var body = expression.propertyorfield(param, nameof(selecteditem));         var member = expression.makememberaccess(body, field.member);         return expression.lambda<func<tmodel, object>>(member, param);     } 

the error i'm receiving when have field multiple parts (i.e. cust.address.state instead of cust.name). error on var member line specified member doesn't exist--which true, since body @ refers parent's child (customer) , not item contains member (address).

here's wish do:

    public expression<func<tmodel, object>> expressionfromfield<tmodel>(fielddefinition<t> field)         tmodel: basemodel<t>     {         var param = expression.parameter(typeof(tmodel), "t");         var body = expression.propertyorfield(param, nameof(selecteditem));         var iwantthis = expression.applyexpressiontofield(field.expression, body);         return expression.lambda<func<tmodel, object>>(iwantthis, param);     } 

any getting point appreciated.

edit: marked possible duplicate of this question; however, real similarity solution (which is, in fact, same). composing expressions not intuitive solution accessing nested properties via expressions (unless one's inuition guided experience, should not assumed). edited question note solution needs suitable paramter of mvc method, limits possible solutions.

what you're looking ability compose expressions, can compose functions:

public static expression<func<t, tresult>> compose<t, tintermediate, tresult>(     expression<func<t, tintermediate>> first,     expression<func<tintermediate, tresult>> second) {     return expression.lambda<func<t, tresult>>(         second.body.replace(second.parameters[0], first.body),         first.parameters[0]); } 

this relies on following method replace instances of 1 expression another:

public class replacevisitor:expressionvisitor {     private readonly expression from, to;     public replacevisitor(expression from, expression to)     {         this.from = from;         this.to = to;     }      public override expression visit(expression ex)     {         if(ex == from) return to;         else return base.visit(ex);     }   }  public static expression replace(this expression ex,     expression from,     expression to) {     return new replacevisitor(from, to).visit(ex); } 

you can take expression selecting property:

expression<func<customer, object>> propertyselector = cust => cust.name; 

and expression selecting object model:

expression<func<customermodel, customer>> modelselector = model => model.customer; 

and compose them:

expression<func<customer, object> magic = modelselector.compose(propertyselector); 

Comments

Popular posts from this blog

javascript - Clear button on addentry page doesn't work -

c# - Selenium Authentication Popup preventing driver close or quit -

tensorflow when input_data MNIST_data , zlib.error: Error -3 while decompressing: invalid block type -