我有2个清单
List<Expression<Func<MyClass, bool>>> andConditions = new List<Expression<Func<MyClass, bool>>>();
List<Expression<Func<MyClass, bool>>> orConditions = new List<Expression<Func<MyClass, bool>>>();
第一个,我想在每个项目之间进行 AND,第二个在每个项目之间进行 OR。最后,我想将 2 个列表与 OR 结合起来。
结果示例:
exprList1 AND exprList1 OR exprList2 OR exprList2 OR exprList2
你能告诉我这件事吗?
PredicateBuilder
nuget包中的LINQKit
。
在促使您手动构建表达式树的所有因素中,动态谓词的需求在典型的业务应用程序中最为常见。幸运的是,可以编写一组简单且可重用的扩展方法,从根本上简化此任务。这就是我们的 PredicateBuilder 类的作用。
首先安装nuget包:
Install-Package LinqKit
之后,您可以使用
PredicateBuilder
组合表达式。长版:
// AND
var combinedAnd = PredicateBuilder.New<MyClass>(true);
foreach (var andCondition in andConditions)
{
combinedAnd = combinedAnd.And(andCondition);
}
// OR
var combinedOr = PredicateBuilder.New<MyClass>(false);
foreach (var orCondition in orConditions)
{
combinedOr = combinedOr.Or(orCondition);
}
var finalExpression = combinedAnd.Or(combinedOr);
基于 LINQ 的简短版本:
var combinedAnd = andConditions
.Aggregate(
PredicateBuilder.New<MyClass>(true),
(current, andCondition) => current.And(andCondition));
var combinedOr = orConditions
.Aggregate(
PredicateBuilder.New<MyClass>(false),
(current, orCondition) => current.Or(orCondition));
var finalExpression = combinedAnd.Or(combinedOr);
PredicateBuilder.New<MyClass>(true)
返回一个返回 true
的初始谓词。将谓词与 AND 运算结合起来是合适的行为,因为它会产生 true && predicate_1 && ... && predicate_n
结果。 PredicateBuilder.New<MyClass>(false)
适用于手术室手术
如果您不能使用外部库,您可以自己实现组合表达式的方法:
public static class ExpressionExtensions
{
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
{
var parameter = Expression.Parameter(typeof(T), "x");
var body = Expression.And(
Expression.Invoke(expr1, parameter),
Expression.Invoke(expr2, parameter)
);
return Expression.Lambda<Func<T, bool>>(body, parameter);
}
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
{
var parameter = Expression.Parameter(typeof(T), "x");
var body = Expression.Or(
Expression.Invoke(expr1, parameter),
Expression.Invoke(expr2, parameter)
);
return Expression.Lambda<Func<T, bool>>(body, parameter);
}
}
并在您的代码中使用它:
var combinedAnd = andConditions.Aggregate((expr1, expr2) => expr1.And(expr2));
var combinedOr = orConditions.Aggregate((expr1, expr2) => expr1.Or(expr2));
var finalExpression = combinedAnd.Or(combinedOr);