I\'m using LinqKit library which allows combining expressions on the fly.
This is a pure bliss for writing Entity Framewok data acess layer because several express
I created improved version of Mic answer:
if (input == null)
return input;
var field = input.Member as FieldInfo;
var prope = input.Member as PropertyInfo;
if ((field != null && field.FieldType.IsSubclassOf(typeof(Expression))) ||
(prope != null && prope.PropertyType.IsSubclassOf(typeof(Expression))))
return Visit(Expression.Lambda<Func<Expression>>(input).Compile()());
return input;
Main advantage is removal DynamicInvoke
that have big overhead and calling Invoke
only when I really need it.
I downloaded sourcecode and tried to analyse it. ExpressionExpander
does not allow to reference expressions that are stored in variables other than constant. It expects expression that Invoke
method is being called upon to reference to object represented by ConstantExpression
, not another MemberExpression
.
So we cannot provide our reusable expression as reference to any member of the class (even public fields, not properties). Nesting member access (like object.member1.member2
... etc) is not supported too.
But this can be fixed by traversing initial expression and recusrsively extracting subfields values.
I have replaced TransformExpr
method code of ExpressionExpander
class to
var lambda = Expression.Lambda(input);
object value = lambda.Compile().DynamicInvoke();
if (value is Expression)
return Visit((Expression)value);
else
return input;
and it works now.
In this solution everything I mentioned before (recursively traversing tree) is done for us by ExpressionTree
compiler :)