c# - 为什么“IQueryable.Where()”在此查询中提供与“IEnumerable.Where()”不同的结果?
问题描述
我正在尝试使用 linq 从 EF Core 数据集中过滤一些行,但我不明白为什么过滤 IEnumerable 与过滤 IQueryable 会给我不同的结果。
var query = _db.Jobs
.IsDelivered()
.Include(a => a.JobExtras)
.Include(a => a.Tips)
.Include(a => a.Payments)
.HasPayments();
var query1 = query
.ToList()
.Where(a => a.Payments.Sum(b => b.Amount)
- a.Price.Value
- a.Discount
- a.JobExtras.Sum(c => c.Price)
- a.Tips.Sum(d => d.Amount)
> 0);
var query2 = query
.Where(a => a.Payments.Sum(b => b.Amount)
- a.Price.Value
- a.Discount
- a.JobExtras.Sum(c => c.Price)
- a.Tips.Sum(d => d.Amount)
> 0);
Debug.WriteLine($"Record Count[Before Where Clause]: {query.Count()}");
Debug.WriteLine($"Record Count[ToList() version]: {query1.Count()}");
Debug.WriteLine($"Record Count[w/out ToList()]: {query2.Count()}");
这是输出:
Record Count[Before Where Clause]: 8379
Record Count[ToList() version]: 5921
Record Count[w/out ToList()]: 0
为什么 IEnumerable 版本产生 5921 条记录,而 IQueryable 版本产生 0 条记录?
解决方案
第一个查询使用 .NET 类型在内存中执行,而Enumerable.Sum()
. 任何传入的空值都将Sum
被跳过,因此您的一些数据正在通过> 0
测试。
第二个查询在数据库中执行并使用 SQL 的SUM
. 如果子句中表达式的任何部分Where
包含 null,则该表达式将评估为 null。获取该表达式并对其进行比较 ( null > 0
) 在 SQL 中始终评估为 false,因此您的所有行都被过滤了。
您的第二个查询可能是可以修复的。我没有证据证明这一点,因为我不知道您的模型(即什么可以为空),并且不确定 EF 是否可以翻译:
.Where(a => a.Payments.Where(x => x != null).Sum(b => b.Amount)
- a.Price.Value
- a.Discount
- a.JobExtras.Where(x => x != null).Sum(c => c.Price)
- a.Tips.Where(x => x != null).Sum(d => d.Amount)
> 0);
推荐阅读
- postgresql - 如何在 JPA 的查询中忽略区分大小写?
- visual-studio-code - 使用 devcontainer.json 中的 postCreateCommand 在 vscode 中打开文件
- hugo - 使用“hugo new”添加页面包
- reactjs - 有没有办法可以防止 IDM 在使用我的网站的任何用户的 PC 上自动下载 pdf
- security - 限制给定 API 的端点子集的 GCP API 密钥
- firebase - 管理客户端 API 密钥的正确 Firestore 架构是什么?
- pyspark - Databricks“数据”->“表”功能不起作用
- python - 嵌套 else 和 if 方法
- javascript - 按钮没有正确禁用角度 js javascript
- ios - 如何在 Xamarin.iOS 中为 ViewController 创建类?