简体   繁体   中英

Generating an Expression<Func<TEntity, bool>> for multi-level expression

Apologies if this is covered in other answers. I searched all night and went through a hundred other solutions but couldn't quite put the puzzle pieces together. I've experimented with LinqPad, PredicateBuilder, ExpressionVisitors, etc. but I'm still scratching my head.

I am trying to implement something slightly more complicated than this but this code shows the issue:

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);
}

This works fine when accessor is something like this: x => x.Value

But not with x => x.Complex.Value or x => x.Complex.MoreComplex.Value

I'm trying to parse expressions from strings such as >=5 or (5...10] and generate Expressions that I can plug into the Where clause of a LINQ-to-EF query (and get translated to T-SQL). This is working fine for the single-level case but I can't figure out how to walk the expression.

In EF, x.Complex.MoreComplex.Value corresponds to SQL Join's. Bonus points if it's possible to convert the accessor into something I can pass into an Include() statement

I put a sample project up on Github: https://github.com/scottt732/ExpressionHelp

Since you are receiving the final value accessor, all you need it to apply the comparison function (ie build the body of the predicate):

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; 
}

Bonus method:

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);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM