我有一个简单的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。似乎没有别的办法起作用。我尝试了vbNull
,isDBNull()
,但没有成功。当总和不为null时,查询工作正常。 defaultifempty(0)
可能有效,但不确定在这种情况下如何使用它。有指针吗?
答案 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)解决方案。