生成表达式<func <tentity,bool =“”>&gt;用于多级表达

时间:2016-02-25 16:53:41

标签: c# entity-framework linq expression-trees

如果其他答案中包含此内容,请致歉。我整夜搜索并经历了其他一百个解决方案,但却无法将拼图拼凑在一起。我已经尝试过LinqPad,PredicateBuilder,ExpressionVisitors等等,但我还在摸不着头脑。

我正在尝试实现比这更复杂的东西,但是此代码显示了问题:

public Expression<Func<TEntity, bool>> GeneratorEqualityTest<TProperty>(Expression<Func<TEntity, TProperty>> accessor, int expectedValue) {
    // Help
    var argument = Expression.Parameter(typeof(TEntity));
    var accessorArgument = Expression.Property(argument, accessor.ToPropertyName());
    // Help

    Predicate = Expression.Lambda<Func<TEntity, bool>>(Expression.Equal(accessorArgument, Expression.Constant(expectedValue)), argument);
}

当访问者是这样的时候,这可以正常工作:x => x.Value

但不是x => x.Complex.Valuex => x.Complex.MoreComplex.Value

我正在尝试解析来自&gt; = 5或(5 ... 10)等字符串的表达式,并生成可以插入LINQ-to-EF查询的Where子句的表达式(并转换为T-SQL)。这对于单级案例工作正常,但我无法弄清楚如何处理表达式。

在EF中,x.Complex.MoreComplex.Value对应于SQL Join。如果可以将访问者转换为我可以传递给Include()语句的内容,则可以获得奖励积分

我在Github上放了一个示例项目:https://github.com/scottt732/ExpressionHelp

1 个答案:

答案 0 :(得分:3)

由于您正在接收最终值访问器,所以您需要它来应用比较函数(即构建谓词的 body ):

public Expression<Func<TEntity, bool>> GeneratorEqualityTest<TProperty>(Expression<Func<TEntity, TProperty>> accessor, TProperty expectedValue)
{
    var body = Expression.Equal(accessor.Body, Expression.Constant(expectedValue));
    var predicate = Expression.Lambda<Func<TEntity, bool>>(body, accessor.Parameters);
    return predicate; 
}

奖金方法:

static class ExpressionUtils
{
    public static IEnumerable<Expression<Func<TEntity, object>>> Includes<TEntity, TProperty>(this Expression<Func<TEntity, TProperty>> accessor)
    {
        var root = accessor.Parameters[0];
        for (var node = accessor.Body as MemberExpression; node != null && node.Expression != root; node = node.Expression as MemberExpression)
            yield return Expression.Lambda<Func<TEntity, object>>(node.Expression, root);
    }
}