简体   繁体   English

Sum()在Entity Framework Query中返回null

[英]Sum() Returns null in Entity Framework Query

I have a big Entity Framework query that includes these lines. 我有一个包含这些行的大型Entity Framework查询。

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)

When I materialize the data, I get the following error: 当我实现数据时,我收到以下错误:

The cast to value type 'Decimal' failed because the materialized value is null. 转换为值类型'Decimal'失败,因为具体化值为null。 Either the result type's generic parameter or the query must use a nullable type. 结果类型的泛型参数或查询必须使用可空类型。

If I change my query as follows (added in two type casts), the error goes away. 如果我按如下方式更改我的查询(添加了两个类型转换),则错误消失。

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)

I do not understand this. 我不明白这个。 ProgramBilling.Amount is a non-nullable Decimal. ProgramBilling.Amount是一个不可为空的Decimal。 If I hover over the Sum() call, Intellisense says it returns type Decimal. 如果我将鼠标悬停在Sum()调用上,Intellisense会说它返回Decimal类型。 And yet additional tests confirmed that, in my second version, totalCharges and totalCredits are both set to null for those rows where ProgramBillings has no data. 而且其他测试证实,在我的第二个版本中,对于那些ProgramBillings没有数据的行, totalChargestotalCredits都设置为null。

Questions: 问题:

  1. I understood Sum() returned 0 for an empty collection. 我知道Sum()为空集合返回0。 Under what circumstances is this not true? 在什么情况下这不是真的?

  2. And if sometimes that is not true, then why when I hover over Sum() , Intellisense shows it returns type Decimal and not Decimal? 如果有时候这不是真的,那么为什么当我将鼠标悬停在Sum() ,Intellisense会显示它返回的类型为Decimal而不是Decimal? It appears Intellisense had the same understanding that I had. 看起来智能感知与我有同样的理解。

EDIT: 编辑:

It would seem that an easy fix is to do something like Sum() ?? 0m 似乎一个简单的解决方法是做Sum() ?? 0m Sum() ?? 0m . Sum() ?? 0m But that's illegal, giving me the error: 但这是非法的,给我错误:

Operator '??' 接线员'??' cannot be applied to operands of type 'decimal' and 'decimal' 不能应用于'decimal'和'decimal'类型的操作数

I understood Sum() returned 0 for an empty collection. 我知道Sum()为空集合返回0。 Under what circumstances is this not true? 在什么情况下这不是真的?

When you're not using LINQ to objects, as is the case here. 当您没有使用LINQ对象时,就像这里的情况一样。 Here you have a query provider that is translating this query into SQL. 这里有一个查询提供程序,可以将此查询转换为SQL。 The SQL operation has different semantics for its SUM operator. SQL操作对其SUM运算符具有不同的语义。

And if sometimes that is not true, then why when I hover over Sum(), Intellisense shows it returns type Decimal and not Decimal? 如果有时候这不是真的,那么为什么当我将鼠标悬停在Sum()上时,Intellisense会显示它返回的类型为Decimal而不是Decimal? It appears Intellisense had the same understanding that I had. 看起来智能感知与我有同样的理解。

The C# LINQ SUM operator doesn't return a nullable value; C#LINQ SUM运算符不返回可为空的值; it needs to have a non-null value, but the SQL SUM operator has different semantics, it returns null when summing an empty set, not 0 . 它需要具有非空值,但S​​QL SUM运算符具有不同的语义,它在求和空集时返回null ,而不是0 The fact that the null value is provided in a context where C# requires a non-null value is the entire reason everything is breaking. 在C#需要非空值的上下文中提供null值的事实是一切都在破坏的全部原因。 If the C# LINQ SUM operator here returned a nullable value, then null could just be returned without any problems. 如果这里的C#LINQ SUM运算符返回了一个可空值,那么就可以返回null而没有任何问题。

It is the differences between the C# operator and the SQL operator it is being used to represent that is causing this error. 它是用于表示导致此错误的C#运算符和SQL运算符之间的差异。

I've got the same issue in one of my EF queries when the collection is empty, one quick fix for this is to cast to nullable decimal : 当集合为空时,我在我的一个EF查询中遇到了同样的问题,一个快速解决方法是转换为可以为空的十进制:

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

hope it helps. 希望能帮助到你。

在.Sum之前添加一个DefaultIfEmpty(0.0M)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM