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

如何将Linq查询Where子句的AND逻辑替换为OR逻辑?

如何将Linq查询的AND过滤逻辑改为OR逻辑?

问题场景

你当前的Linq代码通过循环调用Where来叠加过滤条件,这会导致生成的SQL里多个CompanyCode判断用AND连接——显然这不符合你要匹配任意一个选中公司的需求。

先看下你的原代码:

private IQueryable<viewTable> BaseQuery(Models.TestDataContext db) {
    IQueryable<viewTable> query = db.viewTables;
    foreach (string row in gridCompany.GridView.GetSelectedFieldValues("CompanyCode"))
        query = query.Where(t => t.Comp_Code == row.ToString());
    return query;
}

它生成的SQL是这样的:

SELECT [t0].[Column] FROM [dbo].[viewTable] AS [t0] WHERE ([t0].[CompanyCode] = 'ALPHA') AND ([t0].[CompanyCode] = 'BETA') ORDER BY [t0].[EditDate] DESC

而你想要的是用OR连接的版本:

SELECT [t0].[Column] FROM [dbo].[viewTable] AS [t0] WHERE ([t0].[CompanyCode] = 'ALPHA') OR ([t0].[CompanyCode] = 'BETA') ORDER BY [t0].[EditDate] DESC

解决方案

方法1:用Contains实现(最简洁推荐)

Linq to SQL原生支持Contains方法,它会自动转换成SQL的IN语句——这和多个OR的逻辑完全等价,而且代码更简洁,性能也相当。

修改后的代码:

private IQueryable<viewTable> BaseQuery(Models.TestDataContext db) {
    // 先把选中的公司Code收集到一个集合里
    var selectedCompanyCodes = gridCompany.GridView.GetSelectedFieldValues("CompanyCode")
                                            .Select(row => row.ToString())
                                            .ToList();
    IQueryable<viewTable> query = db.viewTables;
    // 只有当有选中项时才添加过滤条件
    if (selectedCompanyCodes.Any())
    {
        query = query.Where(t => selectedCompanyCodes.Contains(t.Comp_Code));
    }
    return query;
}

这段代码生成的SQL会是:

SELECT [t0].[Column] FROM [dbo].[viewTable] AS [t0] WHERE [t0].[CompanyCode] IN ('ALPHA', 'BETA') ORDER BY [t0].[EditDate] DESC

IN和你要的OR效果完全一致,而且写法更清爽,优先推荐这种方式。

方法2:手动构建OR表达式(适合复杂场景)

如果你的需求更复杂(比如需要动态组合更多复杂条件),可以通过构建表达式树来手动实现OR逻辑:

using System.Linq.Expressions;

private IQueryable<viewTable> BaseQuery(Models.TestDataContext db) {
    var selectedCompanyCodes = gridCompany.GridView.GetSelectedFieldValues("CompanyCode")
                                            .Select(row => row.ToString())
                                            .ToList();
    IQueryable<viewTable> query = db.viewTables;
    
    // 没有选中项直接返回原查询
    if (!selectedCompanyCodes.Any())
        return query;

    // 初始化第一个过滤条件
    Expression<Func<viewTable, bool>> predicate = t => t.Comp_Code == selectedCompanyCodes[0];
    // 循环叠加OR条件
    for (int i = 1; i < selectedCompanyCodes.Count; i++)
    {
        string currentCode = selectedCompanyCodes[i];
        // 把新的条件和之前的条件用OR合并
        predicate = Expression.Lambda<Func<viewTable, bool>>(
            Expression.OrElse(predicate.Body, 
                Expression.Equal(
                    Expression.Property(predicate.Parameters[0], "Comp_Code"), 
                    Expression.Constant(currentCode)
                )),
            predicate.Parameters[0]
        );
    }
    // 应用构建好的OR过滤条件
    query = query.Where(predicate);
    return query;
}

这种方法会生成你期望的多个OR连接的SQL语句,适合需要自定义复杂逻辑的场景。

为什么原代码会生成AND?

简单说:每一次调用Where都是在已有查询的基础上追加过滤条件,Linq to SQL会自动把这些独立的过滤条件用AND组合起来。而我们需要的是把所有公司Code的判断合并成一个“满足任意一个即可”的条件,所以不能多次调用Where,而是要把多个条件合并成一个表达式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 16:22:43