如何在循环中为IQueryable变量添加Where与OR条件
动态为IQueryable叠加OR条件的实现方案
你需要生成包含多个OR条件的SQL查询,但直接使用Where方法会叠加AND逻辑,无法满足需求。以下是两种可行的实现方案:
方案一:使用LinqKit的PredicateBuilder(推荐)
LinqKit提供的PredicateBuilder可以轻松组合OR/AND条件,需要先通过NuGet安装LinqKit.Microsoft.EntityFrameworkCore包。
代码示例:
using LinqKit; // 初始化基础查询,包含IsDeleted过滤 var baseQuery = DbContext.EmployeeSearches.AsQueryable(); var predicate = PredicateBuilder.New<EmployeeSearch>(e => !e.IsDeleted); // 模拟12次迭代的名称匹配逻辑 for (int x = 0; x < 12; x++) { string targetName; if (x == 0) { targetName = fd.Value.ToString() == "None" ? "None" : filter.Value.ToString(); } else { // 替换为你实际的第x个EmployeeName值 targetName = $"EmployeeName_{x}"; } // 叠加OR条件:匹配null/None或指定名称 if (targetName == "None") { predicate = predicate.Or(e => e.EmployeeName == null || e.EmployeeName == "None"); } else { predicate = predicate.Or(e => e.EmployeeName == targetName); } } // 应用组合后的谓词生成最终查询 var result = baseQuery.AsExpandable().Where(predicate);
方案二:手动构建表达式树(无第三方依赖)
如果不想引入外部包,可以手动通过表达式树组合OR条件:
代码示例:
using System.Linq.Expressions; // 初始化基础查询 var baseQuery = DbContext.EmployeeSearches.AsQueryable(); Expression<Func<EmployeeSearch, bool>> combinedPredicate = e => !e.IsDeleted; for (int x = 0; x < 12; x++) { string targetName; if (x == 0) { targetName = fd.Value.ToString() == "None" ? "None" : filter.Value.ToString(); } else { // 替换为实际的名称值 targetName = $"EmployeeName_{x}"; } // 创建当前迭代的条件表达式 Expression<Func<EmployeeSearch, bool>> currentPredicate; if (targetName == "None") { currentPredicate = e => e.EmployeeName == null || e.EmployeeName == "None"; } else { currentPredicate = e => e.EmployeeName == targetName; } // 组合现有表达式与当前表达式(OR逻辑) var parameter = Expression.Parameter(typeof(EmployeeSearch)); var combinedBody = Expression.OrElse( Expression.Invoke(combinedPredicate, parameter), Expression.Invoke(currentPredicate, parameter) ); combinedPredicate = Expression.Lambda<Func<EmployeeSearch, bool>>(combinedBody, parameter); } // 应用最终条件 var result = baseQuery.Where(combinedPredicate);
两种方案最终生成的SQL都会符合你期望的格式:
Select * from Employee Where IsDeleted = 0 AND (EmployeeName = 'None' OR EmployeeName='John' OR EmployeeName='Lucy')
内容的提问来源于stack exchange,提问作者Alevel
相关产品推荐
相关产品推荐

