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

C#中如何通过LINQ实现多业务单元条件的批量记录查询?

多业务单元筛选问题解决方法

问题描述

我开发了支持多条件筛选的前端,其中包含业务单元(Business Units)筛选项。单业务单元筛选时,URL为https://localhost:7206/api/v1/lots?businessUnits=SCP_PP,功能正常。现在需要实现多业务单元筛选,URL格式为https://localhost:7206/api/v1/lots?businessUnits=SCP_PP%2CNAG,该参数在C#后端接收为字符串"SCP_PP, NAG"。尝试通过拆分字符串为数组,循环添加Where条件,但无法返回符合多条件的记录(单条件筛选正常)。

原查询实现代码:

public List<Lot> GetLots(DateTime? dateFrom, DateTime? dateTo, bool? includeGraded, string? status, string? businessUnits)
{
    var lots = _gradingContext.Lots.AsNoTracking().AsQueryable();

    if(businessUnits!= null)
    {
        if (businessUnits.Contains(','))
        {
            string[] businessUnitsTemp = businessUnits.Split(",");
            foreach (var unit in businessUnitsTemp)
            {
                lots = lots.Where(x => x.BusinessUnit.Equals(businessUnitsTemp));
            }
        }
        else
        {
            lots = lots.Where(x => x.BusinessUnit.Equals(businessUnits));
        }
    }

    return lots.ToList();
}

问题根源

  1. 循环条件错误:循环中误将数组businessUnitsTemp作为匹配值,而非当前循环的unit变量,导致筛选逻辑完全失效。
  2. 未处理空格:后端接收的参数是"SCP_PP, NAG",拆分后第二个元素带前置空格,无法匹配数据库中的"NAG"。
  3. 逻辑错误:循环叠加Where条件会生成**逻辑与(AND)规则,要求记录同时匹配所有业务单元,而实际需要的是逻辑或(OR)**规则。

修正方案

方案1:使用Contains实现简单OR筛选(推荐)

直接用集合的Contains方法替代循环,简洁高效:

public List<Lot> GetLots(DateTime? dateFrom, DateTime? dateTo, bool? includeGraded, string? status, string? businessUnits)
{
    var lots = _gradingContext.Lots.AsNoTracking().AsQueryable();

    if (!string.IsNullOrEmpty(businessUnits))
    {
        // 拆分参数、去除空格、过滤空值
        var businessUnitList = businessUnits.Split(',')
                                            .Select(unit => unit.Trim())
                                            .Where(unit => !string.IsNullOrEmpty(unit))
                                            .ToList();
        
        if (businessUnitList.Any())
        {
            // 筛选BusinessUnit在列表中的记录(OR逻辑)
            lots = lots.Where(x => businessUnitList.Contains(x.BusinessUnit));
        }
    }

    // 其他筛选逻辑...

    return lots.ToList();
}

方案2:使用PredicateBuilder实现复杂OR筛选

如果后续需要扩展更复杂的OR条件,可以借助LinqKit的PredicateBuilder(需先安装LinqKit NuGet包):

using LinqKit;

public List<Lot> GetLots(DateTime? dateFrom, DateTime? dateTo, bool? includeGraded, string? status, string? businessUnits)
{
    var lots = _gradingContext.Lots.AsNoTracking().AsQueryable();

    if (!string.IsNullOrEmpty(businessUnits))
    {
        var businessUnitList = businessUnits.Split(',')
                                            .Select(unit => unit.Trim())
                                            .Where(unit => !string.IsNullOrEmpty(unit))
                                            .ToList();
        
        if (businessUnitList.Any())
        {
            var predicate = PredicateBuilder.New<Lot>(false);
            foreach (var unit in businessUnitList)
            {
                var currentUnit = unit; // 捕获循环变量,避免闭包陷阱
                predicate = predicate.Or(x => x.BusinessUnit.Equals(currentUnit));
            }
            lots = lots.Where(predicate);
        }
    }

    // 其他筛选逻辑...

    return lots.ToList();
}

关键注意事项

  • 必须处理参数中的空格:前端传参解码后带空格,Trim()是匹配数据库值的前提。
  • 过滤空元素:避免参数末尾带逗号导致拆分出空字符串,干扰筛选结果。
  • 闭包陷阱:使用PredicateBuilder循环时,需将循环变量赋值给局部变量,否则所有条件会复用最后一个循环值。

内容的提问来源于stack exchange,提问作者shizz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 01:37:50