Where方法写多个条件直接用&&或||连接,无需冗余括号;注意null安全需先判空再访问;性能上避免循环中反复调用ToList();EF Core中异步需调用ToListAsync()等终结方法。

Where 方法怎么写多个条件:用 && 和 || 就行,别套括号套晕自己
多个条件组合筛选,最直接的方式就是在 Where 的 lambda 表达式里用 &&(且)或 ||(或)。C# 编译器能正确推导类型,不需要手动加括号包裹整个表达式——加多了反而容易出错。
常见错误现象:Where(x => (x.Status == "Active") && (x.Age > 18)) 这种写法没错,但括号纯属冗余;更糟的是有人写成 Where((x) => x.Status == "Active" && x.Age > 18),多了一对括号导致编译失败。
- 推荐写法:
list.Where(x => x.Status == "Active" && x.Age >= 21) - 如果条件逻辑复杂,拆成变量更易读:
bool isEligible = x.Status == "Active" && x.Age >= 21 && !x.IsBanned;,再Where(x => isEligible)—— 不行,这会报错,因为isEligible是 bool 常量,不是表达式树;得写成函数或保持内联 - 数据库查询(如 EF Core)中,
&&会被转成 SQL 的AND,||转成OR,但!=在某些旧版 EF 中可能不生成高效 SQL,优先用== false或!x.IsActive
Where 筛选 null 值时,空引用异常比你想象中来得快
如果你的集合里有 null 元素,又在 Where 里直接调用属性或方法,运行时立刻崩:NullReferenceException。这不是 LINQ 的锅,是 C# 对 null 的零容忍。
使用场景:从 API 或数据库查出来的集合,字段可能为 null(比如 string Name 或 DateTime? CreatedAt)。
- 安全写法:先判空再访问,
items.Where(x => x != null && x.Name?.Length > 0) -
?.可以防止崩溃,但要注意返回值是可空类型,比如x.Name?.Contains("test")返回bool?,不能直接和true比较;得写成x.Name?.Contains("test") == true - EF Core 中,
x.Name != null && x.Name.Contains("a")会被翻译成 SQL 的IS NOT NULL AND LIKE;但x.Name?.Contains("a") == true在部分版本里无法翻译,直接抛NotSupportedException
Where 性能陷阱:别在循环里反复调用,尤其配合 ToList()
Where 本身不执行,只是构建一个延迟执行的 IEnumerable。但每次遍历它、或者调用 Count()、ToList(),都会重新执行整个筛选逻辑。如果写在 for 循环里,性能雪崩。
常见错误现象:列表有 1000 项,你在循环里写了 10 次 data.Where(x => x.Type == type).ToList(),实际做了 10 次全量扫描,而不是复用结果。
- 高频使用前先物化:
var activeUsers = users.Where(x => x.IsActive).ToList();,后续直接用activeUsers - 如果只是查一次,又想链式操作,
Where后接Select或FirstOrDefault没问题;但别接ToList()再接另一个Where,那等于白筛一遍 - 大数据量 + 多次筛选时,考虑用
Dictionary或Lookup预分组:var lookup = items.ToLookup(x => x.Category);,之后lookup["A"]是 O(1) 查找
Where 和 WhereAsync 不是一回事:EF Core 里漏掉 Async 后缀就同步跑了
EF Core 提供了 Where(同步)和 WhereAsync(异步),但注意:WhereAsync 并不存在。真正异步的是 ToListAsync()、FirstOrDefaultAsync() 这些终结方法。你写 query.Where(...) 永远是同步构建表达式树,不发 SQL。
错误理解:“加了 async 就自动异步” —— 实际上,只有调用带 Async 后缀的终结方法时,才会真正异步执行数据库查询。
- 正确异步写法:
var result = await context.Users.Where(u => u.IsActive).ToListAsync(); - 错误写法:
var query = context.Users.Where(...); await query.ToList();——ToList()没有 async 版本,会同步阻塞 - 如果忘了
await,编译器可能不报错(返回Task),但运行时会同步执行,还可能引发死锁(尤其 ASP.NET Framework)- >
事情说清了就结束。最常被忽略的是 null 安全和异步终结点——前者让程序崩在生产环境,后者让接口悄悄变慢。











