Linq查询处理空值

3
From r In ReceiptLines
Where 
r.RECEIPT.RECEIPTDATE >= _reportStartDate 
And r.RECEIPT.RECEIPTDATE <= _reportEndDate
Let amount = r.QUANTITY * r.PRICE
Let discount = r.RECEIPTDISCOUNTs.Sum(Function(d) d.DISCOUNT) 
where discount > 0
Group By Department = r.ITEMSTYLE.ITEM.CATEGORY.DEPARTMENT.DEPARTMENTNAME
Into Sales = Sum(amount - discount), 
Average = Average(amount - discount), 
Count = Count()

我正在从ReceiptLine、Receipt和ReceiptDiscount表中获取所有部门及其销售额、平均值和数量。我遇到的问题是,如果我删除where discount > 0,就会出现空异常。但是如果我包括它,那么我只会得到有折扣的销售额。如何编写查询以获得所有销售额减去折扣(如果有的话)。非常感谢您的帮助。


看起来你的代码是VB.NET。我加了这个标签,如果不正确,你可以更正。 - Albin Sunnanbo
2个回答

8

这是LINQ2SQL常见的陷阱。

在SQL中,SUM函数如果集合中没有任何项,则返回null,但Enumerable.Sum()的签名返回一个int类型。当SQL查询返回null时,LINQ2SQL提供程序期望一个整数,从而导致运行时异常。

解决方法是将求和结果转换为可空整数类型,然后使用GetValueOrDefault将null情况转换为0。

替换为:

Let discount = r.RECEIPTDISCOUNTs.Sum(Function(d) d.DISCOUNT) 

使用

Let discount = CType(r.RECEIPTDISCOUNTs.Sum(Function(d) d.DISCOUNT), Integer?).GetValueOrDefault(0)

1

你试过了吗:

...
Let amount = r.QUANTITY * r.PRICE
Let nDiscount = r.RECEIPTDISCOUNTs.Sum(Function(d) d.DISCOUNT) 
Let discount = IIf(nDiscount == Nothing, 0, nDiscount)
Group By Department = r.ITEMSTYLE.ITEM.CATEGORY.DEPARTMENT.DEPARTMENTNAME
...

2
我认为Muthu的代码看起来像VB.NET语言,而在VB.NET中三元运算符的发音是IF(Condition, TrueValue, FalseValue) - Albin Sunnanbo
是的!我已经习惯了长时间使用C#编码。没有注意到这一点。谢谢。 - Kamyar
2
而在VB.NET中,“null”被拼写为“Nothing”。如果你习惯了C#,那么写VB.NET就像是在键盘上倒了两杯咖啡。你照常打字,但到处都是红色的波浪线。 - Albin Sunnanbo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接