LINQ SUM可空

时间:2018-09-22 17:53:00

标签: vb.net linq linq-to-entities

我有一个简单的linq查询

(From a In db.payments Group Join b In db.interestcharges On  a.pid Equals b.pid Into totalinterest = Group, TotalInterestReceived = Sum(b.interest)) select a, TotalInterestReceived).toList()

b.interest是DB中的十进制类型。

投掷

"The cast to value type 'System.Decimal' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type."

这是因为InterestCharges表可能没有pid的任何兴趣记录。

我尝试过sum(if(b.interest=nothing,0,b.interest),但是LINQ将其翻译为if(b.interest=0, 0, b.interest),因此它从不检查null。似乎没有别的办法起作用。我尝试了vbNullisDBNull(),但没有成功。当总和不为null时,查询工作正常。 defaultifempty(0)可能有效,但不确定在这种情况下如何使用它。有指针吗?

1 个答案:

答案 0 :(得分:1)

GROUP JOIN语句表明您正在尝试LEFT OUTER JOIN。这就是为什么您收到NULL问题的原因。通过将JOIN用作INNER JOIN,您不会迷失于此,但这也意味着您将只看到那些具有感兴趣值的项目。

(FROM a in db.Payments 
Join b in db.InterestCharges ON a.pid Equals b.Pid 
SELECT a, TotalInterestReceived = SUM(b.Interest) 
).toList()

可以生成一个子选择,该子选择可以获取您希望的值。这样做的目的是获得所有付款,然后基本上增加利息费用(如果没有,则为0)。

(From a In db.Payments 
Select a 
, TotalInterestRecieved = (From b in db.InterestCharges 
                           Where b.pid = a.pid
                           select b.Interest).DefaultIfEmpty(0).Sum() 
).ToList

编辑:

另一个选择是完全绕过EF。在数据库中构建视图并直接查询该视图,而不是尝试通过LINQ访问基础数据。

我将要提出的大多数其他建议包括遍历“付款”的初始列表并根据需要填充值。对于少量的“付款”来说,这很好,但这是一种O(n)解决方案。