将表达式转换为表达式<Func<T, bool>>
Convert Expression to Expression<Func<T, bool>>
如果表达式的实例是在 T
上创建的,是否可以将 Expression
转换为 Expression<Func<T, bool>>
?
最后我有列表 List<Expression>
并且需要在 Expression<Func<T, bool>>
上生成,其中 List<Expression>
的每个表达式都与 AND
.
聚合
是;只需调用 Expression.Lambda<Func<T, bool>>(..., parameter)
,其中 ...
是由您要组合的表达式组成的表达式。
你可能想要 list.Aggregate(Expressions.AndAlso)
。
如果您的表达式并非全部相同 ParameterExpression
,您需要重写它们才能做到这一点。 (使用 ExpressionVisitor
)
这是可能的,但列表中的每个表达式实际上必须是一个 Expression<Func<T, bool>>
实例。
编辑: 事实证明,您使用的 Kendo.Mvc.IFilterDescriptor.CreateFilterExpression 实际上构建了 MethodCallExpression
s.
以下辅助方法应该可以完成这项工作(适用于 lambda 和方法调用表达式):
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);
}
}
}
如果表达式的实例是在 T
上创建的,是否可以将 Expression
转换为 Expression<Func<T, bool>>
?
最后我有列表 List<Expression>
并且需要在 Expression<Func<T, bool>>
上生成,其中 List<Expression>
的每个表达式都与 AND
.
是;只需调用 Expression.Lambda<Func<T, bool>>(..., parameter)
,其中 ...
是由您要组合的表达式组成的表达式。
你可能想要 list.Aggregate(Expressions.AndAlso)
。
如果您的表达式并非全部相同 ParameterExpression
,您需要重写它们才能做到这一点。 (使用 ExpressionVisitor
)
这是可能的,但列表中的每个表达式实际上必须是一个 Expression<Func<T, bool>>
实例。
编辑: 事实证明,您使用的 Kendo.Mvc.IFilterDescriptor.CreateFilterExpression 实际上构建了 MethodCallExpression
s.
以下辅助方法应该可以完成这项工作(适用于 lambda 和方法调用表达式):
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);
}
}
}