Is there a particular reason LinqKit's expander can't pick up Expressions from fields?

前端 未结 2 1682
谎友^
谎友^ 2020-12-23 14:59

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

相关标签:
2条回答
  • 2020-12-23 15:12

    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.

    0 讨论(0)
  • 2020-12-23 15:27

    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 :)

    0 讨论(0)
提交回复
热议问题