You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于输入参数动态创建带OR逻辑的LINQ查询?

问题

假设我有一个整数列表,函数接收两个条件输入参数用于过滤,参数结构如下:

public class Input
{
    public string Operation = "less than"; // 可取值 <=, >=, !=, ==, <, > 等 
    public int Filter = 9;
}

我希望根据传入的条件进行动态过滤,且过滤逻辑为OR关系。请问如何动态创建LINQ查询,避免如下所示的硬编码所有条件组合:

/*
Input one = { Operation = "less than" , Filter = 9 }
Input two = { Operation = "equal to", Filter =10 }
int[] arrayToFilter = { 1,2,3,4,5,6,7,8,9,10,11,12 }
*/
public int[] MyFilter(Input one, Input two, int[] arrayToFilter)
{
    if (one.Operation == "less than" && two.Operation == "equal to")
    {
        return arrayToFilter.Where(x => x < one.Filter || x == two.Filter).ToArray();
    }

    if (one.Operation == "less than or equal to" && two.Operation == "greater than")
    {
        return arrayToFilter.Where(x => x <= one.Filter || x > two.Filter).ToArray();
    }
    // 其余所有组合(如何避免这种写法?)
    return arrayToFilter;
}
解决方案

方法一:委托映射+动态组合(适合内存集合)

先把每个Input条件转换成独立的判断委托,再用OR逻辑组合,完全避免硬编码组合场景:

  1. 编写操作符到委托的映射方法:
private Func<int, bool> GetFilterPredicate(Input input)
{
    return input.Operation switch
    {
        "less than" => x => x < input.Filter,
        "less than or equal to" => x => x <= input.Filter,
        "greater than" => x => x > input.Filter,
        "greater than or equal to" => x => x >= input.Filter,
        "equal to" => x => x == input.Filter,
        "not equal to" => x => x != input.Filter,
        _ => x => true // 默认返回true,即不过滤该条件
    };
}
  1. 在过滤方法中组合OR逻辑:
public int[] MyFilter(Input one, Input two, int[] arrayToFilter)
{
    var predicateOne = GetFilterPredicate(one);
    var predicateTwo = GetFilterPredicate(two);
    // 满足任意一个条件即可保留
    return arrayToFilter.Where(x => predicateOne(x) || predicateTwo(x)).ToArray();
}

这种方式的优势是:新增操作符只需在映射方法里加分支,无需修改过滤逻辑,维护成本极低。

方法二:表达式树构建(适合EF等IQueryable场景)

如果你的数据源是EF这类需要生成SQL查询的IQueryable,用表达式树可以让过滤逻辑在数据库端执行,避免内存全量加载:

  1. 生成单个条件的表达式:
private Expression<Func<int, bool>> GetFilterExpression(Input input)
{
    var parameter = Expression.Parameter(typeof(int), "x");
    var constant = Expression.Constant(input.Filter);
    var body = input.Operation switch
    {
        "less than" => Expression.LessThan(parameter, constant),
        "less than or equal to" => Expression.LessThanOrEqual(parameter, constant),
        "greater than" => Expression.GreaterThan(parameter, constant),
        "greater than or equal to" => Expression.GreaterThanOrEqual(parameter, constant),
        "equal to" => Expression.Equal(parameter, constant),
        "not equal to" => Expression.NotEqual(parameter, constant),
        _ => Expression.Constant(true)
    };
    return Expression.Lambda<Func<int, bool>>(body, parameter);
}
  1. 合并两个表达式的OR逻辑:
public int[] MyFilter(Input one, Input two, int[] arrayToFilter)
{
    var exprOne = GetFilterExpression(one);
    var exprTwo = GetFilterExpression(two);
    // 合并两个表达式的OR判断
    var combinedExpr = Expression.Lambda<Func<int, bool>>(
        Expression.OrElse(exprOne.Body, exprTwo.Body),
        exprOne.Parameters.Single()
    );
    return arrayToFilter.AsQueryable().Where(combinedExpr).ToArray();
}

内容的提问来源于stack exchange,提问作者just-an-average-programmer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 14:35:31