kosnkov
kosnkov

Reputation: 5911

Convert Expression to Expression<Func<T, bool>>

Is that possible to convert Expression to Expression<Func<T, bool>> if instance of Expression was created on T ?

At the end I have list List<Expression> and need to produce on Expression<Func<T, bool>> where each expression of List<Expression> is agregated with AND.

Upvotes: 5

Views: 4564

Answers (2)

Ivan Stoev
Ivan Stoev

Reputation: 205569

It's possible, but every expression in the list must actually be a Expression<Func<T, bool>> instance.

EDIT: It turns out that you use Kendo.Mvc.IFilterDescriptor.CreateFilterExpression which actually builds a MethodCallExpressions.

The following helper method should do the job (works with both lambda and method call expressions):

public static class Utils
{
    public static Expression<Func<T, bool>> And<T>(List<Expression> expressions)
    {
        var item = Expression.Parameter(typeof(T), "item");
        var body = expressions[0].GetPredicateExpression(item);
        for (int i = 1; i < expressions.Count; i++)
            body = Expression.AndAlso(body, expressions[i].GetPredicateExpression(item));
        return Expression.Lambda<Func<T, bool>>(body, item);
    }

    static Expression GetPredicateExpression(this Expression target, ParameterExpression parameter)
    {
        var lambda = target as LambdaExpression;
        var body = lambda != null ? lambda.Body : target;
        return new ParameterBinder { value = parameter }.Visit(body);
    }

    class ParameterBinder : ExpressionVisitor
    {
        public ParameterExpression value;
        protected override Expression VisitParameter(ParameterExpression node)
        {
            return node.Type == value.Type ? value : base.VisitParameter(node);
        }
    }
}

Upvotes: 2

SLaks
SLaks

Reputation: 887275

Yes; just call Expression.Lambda<Func<T, bool>>(..., parameter), where ... is an expression composed of the expressions you want to combine.

You'd probably want list.Aggregate(Expressions.AndAlso).

If your expressions don't all share the same ParameterExpression, you'll need to rewrite them to do so. (use ExpressionVisitor)

Upvotes: 6

Related Questions