【发布时间】:2019-09-11 18:59:51
【问题描述】:
我正在尝试使用 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 条记录?
【问题讨论】:
-
您计算中的这些列中是否有
NULLs?NULL上的任何数学或逻辑都会产生NULL,包括NULL > 0->NULL这不是真的,所以它在功能上等同于假。 -
我想也许也是这样,所以我删除了唯一可以为空的“价格”但结果相同的术语。另外,如果是这样的话,那不应该像 query2 一样影响 query1 吗?
-
没有。当您调用
ToList时,它会执行查询,此时您正在对 .NET 类型/值进行操作。Sum将忽略null而不是产生null,Count将计算null项目而不是忽略它。如果您的源数据没有NULLs,那将没有实际意义,但我认为当您没有要聚合的项目时,您可能会收到NULL。
标签: c# entity-framework linq entity-framework-core