.net - Combining 2 LambdaExpressions into 1 LamdaExpression -


i dynamically generating expression trees sent off linq entities. providing framework , allow developers specify output columns lambda expressions.

for instance, have column can specify way pull value database is:

p => p.aliases.count() 

and column is:

p => p.names.where(n => n.startswith("hello")) 

the problem here need combine both of these single expression.

my first attempt was:

getter = field.selectorexpression.body; 

and error message the parameter 'p' not bound in specified linq entities query expression makes since because linq can't know p in p.aliases.count().

the next thing tried was:

getter = expression.invoke(field.orderbyselector, new[] {parameter}); 

however, recieve message the linq expression node type 'invoke' not supported in linq entities. makes since because don't expect sql server know how run lambda expressions.

right have expression:

item => new myclass {      somevalue = item.name, // generated other code     anothervalue = item.someothercolumn, // there can lots of these     aliascount = p.aliases.count() // here of course problem } 

obviously want replace expression "p" when building expression item (which have , know how use).

tldr there easy way replace instances of parameter usaged in lambdaexpression expression?

an example started.

class program     {         static void main(string[] args)         {             expression<func<foo1, int>> expression1 = => a.foo2s.count();              expression<func<ienumerable<foo1>, ienumerable<foo2>>> expression2 =                 => a.select(b => new foo2 { string1 = "asdf", foo2count = 3 });              memberassignment foo2countassignment = getexpression(expression2);             // in case, constantexpression value of 3.             var expression = foo2countassignment.expression constantexpression;              expression<func<ienumerable<foo1>, ienumerable<foo2>>> expression3 =                 => a.select(b => new foo2 { string1 = "asdf", foo2count = b.foo2s.count() });              foo2countassignment = getexpression(expression3);             // in case, expression<func<foo1, int>>             // same expression1, except has different parameter.             var expressionresult = foo2countassignment.expression methodcallexpression;             var foo2spropertyexpression = expressionresult.arguments[0] memberexpression;             // "b".foo2scount()             var thebparameter = foo2spropertyexpression.expression parameterexpression;               // practical demonstartion.             var mce = expression1.body methodcallexpression;              var selectstatement = expression2.body methodcallexpression;             var selectlambda = selectstatement.arguments[1] expression<func<foo1, foo2>>;             var bparameter = selectlambda.parameters[0];              var me = mce.arguments[0] memberexpression;             var newexpression = me.update(bparameter);             // go expression tree using update create new expression till first level.             // unless find way replace me.         }          public static memberassignment getexpression(expression<func<ienumerable<foo1>, ienumerable<foo2>>> expression2)         {             // a."select"             var selectstatement = expression2.body methodcallexpression;             // a.select("b => new foo2..."             var selectlambda = selectstatement.arguments[1] expression<func<foo1, foo2>>;             // a.select(b => "new foo2"             var newfoo2statement = selectlambda.body memberinitexpression;             // a.select(b => new foo2 {string1 = "asdf", !!foo2count = 3!! })             return newfoo2statement.bindings[1] memberassignment;         }     }          public class foo1     {         public ienumerable<foo2> foo2s { get; set; }     }      public class foo2     {         public string string1 { get; set; }         public int foo2count { get; set; }     } 

basically program traverses expression tree , lays out each node. can use ".gettype()" on each node exact type of expression , deal them accordingly. (hardcoded , known before hand in example).

the last example demonstrates how can replace " " in a.foo2s.count() " b " can replaced second longer expression.

then ofcourse need think of way can auto detect , replicated of expression 1 backinto expression 2.

not easy task.


Comments

Popular posts from this blog

objective c - Change font of selected text in UITextView -

php - Accessing POST data in Facebook cavas app -

c# - Getting control value when switching a view as part of a multiview -