合并 2 个列表,List<Expression<Func>> 在它们之间使用 OR 并且在项目之间使用 OR/AND [重复]

问题描述 投票:0回答:1

我有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 

你能告诉我这件事吗?

c# .net linq lambda expression
1个回答
0
投票

您可以使用

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);
© www.soinside.com 2019 - 2024. All rights reserved.