我有一个包含这些行的大型实体框架查询。
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)当我将数据物化时,我会得到以下错误:
转换为值类型'Decimal‘失败,因为物化值为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()调用上,Intellisense表示它返回Decimal类型。然而,其他测试证实,在我的第二个版本中,对于那些没有数据的行,totalCharges和totalCredits都被设置为null。
问题:
Sum()返回了一个空集合的0。在什么情况下,这不是真的呢?Sum()上悬停时,Intellisense显示它返回类型为Decimal而不是Decimal?看起来Intellisense和我有同样的理解。编辑:
似乎一个简单的解决方法就是做一些类似于Sum() ?? 0m的事情。但这是违法的,给我一个错误:
接线员??不能应用于“十进制”和“十进制”类型的操作数。
发布于 2015-01-09 18:45:16
我理解Sum()返回了一个空集合的0。在什么情况下,这不是真的呢?
当您不使用LINQ对象时,就像这里的情况一样。这里有一个查询提供程序,它将此查询转换为SQL。SQL操作对其SUM运算符具有不同的语义。
如果有时这不是真的,那么为什么当我在Sum()上悬停时,Intellisense显示它返回类型为Decimal而不是Decimal?看起来Intellisense和我有同样的理解。
summing运算符不返回可空值;它需要有一个非空值,但是C#和运算符有不同的语义,它在对空集求和时返回null,而不是0。null值是在C#需要非空值的上下文中提供的,这是一切都中断的原因。如果这里的C# LINQ运算符返回一个可为空的值,那么null就可以没有任何问题地返回。
导致此错误的是它用来表示的C#运算符与它所表示的SQL运算符之间的差异。
发布于 2016-02-16 11:37:47
当集合为空时,我在EF查询中遇到了同样的问题,一个快速修复方法是将其转换为可空的十进制:
var total = db.PaiementSet.Sum(o => (Decimal?)o.amount) ?? 0M;希望能帮上忙。
发布于 2017-06-15 08:47:54
在.Sum之前添加一个DefaultIfEmpty(0.0M)
https://stackoverflow.com/questions/27866922
复制相似问题