sum() 在实体框架查询中返回 null

本文关键字:查询 返回 null 框架 实体 sum | 更新日期: 2023-09-27 18:37:08

我有一个包含这些行的大型实体框架查询。

var programs = from p in Repository.Query<Program>()
               where p.OfficeId == CurrentOffice.Id
               let totalCharges = p.ProgramBillings.Where(b => b.Amount > 0 && b.DeletedDate == null).Select(b => b.Amount).Sum()
               let totalCredits = p.ProgramBillings.Where(b => b.Amount < 0 && b.DeletedDate == null).Select(b => -b.Amount).Sum()
               let billingBalance = (totalCharges - totalCredits)

当我具体化数据时,出现以下错误:

强制转换为值类型"十进制"失败,因为具体化值为 null。结果类型的泛型参数或查询必须使用可为 null 的类型。

如果我按如下方式更改查询(以两种类型转换添加),则错误将消失。

var programs = from p in Repository.Query<Program>()
               where p.OfficeId == CurrentOffice.Id
               let totalCharges = (decimal?)p.ProgramBillings.Where(b => b.Amount > 0 && b.DeletedDate == null).Select(b => b.Amount).Sum()
               let totalCredits = (decimal?)p.ProgramBillings.Where(b => b.Amount < 0 && b.DeletedDate == null).Select(b => -b.Amount).Sum()
               let billingBalance = (totalCharges - totalCredits)

我不明白这一点。 ProgramBilling.Amount 是一个不可为空的小数。如果我将鼠标悬停在Sum()调用上,智能感知会说它返回十进制类型。然而,其他测试证实,在我的第二个版本中,对于ProgramBillings没有数据的那些行,totalChargestotalCredits都设置为 null。

问题:

  1. 我明白Sum()为空集合返回 0。在什么情况下这不是真的?

  2. 如果有时这不是真的,那么为什么当我将鼠标悬停在 Sum() 上时,智能感知显示它返回十进制类型而不是十进制?看来Intellisense的理解和我一样。

编辑:

似乎一个简单的解决方法是做类似的事情 Sum() ?? 0m .但这是非法的,给了我错误:

运算符"?

?"不能应用于类型为"十进制"和"十进制"的操作数

sum() 在实体框架查询中返回 null

我理解 Sum() 为空集合返回 0。在什么情况下这不是真的?

当您不使用 LINQ 到对象时,就像这里的情况一样。 在这里,您有一个将此查询转换为 SQL 的查询提供程序。 SQL 操作对其 SUM 运算符具有不同的语义。

如果有时这不是真的,那么为什么当我将鼠标悬停在 Sum() 上时,智能感知显示它返回十进制类型而不是十进制?看来Intellisense的理解和我一样。

C# LINQ SUM 运算符不返回可为 null 的值;它需要具有非 null 值,但 SQL SUM 运算符具有不同的语义,它在对空集求和时返回 null,而不是0null值是在 C# 需要非 null 值的上下文中提供的,这一事实是一切中断的全部原因。 如果此处的 C# LINQ SUM 运算符返回可为 null 的值,则null可以毫无问题地返回。

正是

C# 运算符和用于表示的 SQL 运算符之间的差异导致了此错误。

当集合为空时,我的一个EF查询中遇到了同样的问题,一个快速解决方法是转换为可为空的十进制:

var total = db.PaiementSet.Sum(o => (Decimal?)o.amount) ?? 0M;

希望对您有所帮助。

之前 .总和加一个默认如果空(0.0M)