Обработка запросов Linq с нулевыми значениями

#vb.net #linq #entity-framework

#vb.net #linq #entity-framework

Вопрос:

 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, я получаю исключение null. Но если я включу это, то получу продажи только со скидкой.
Как бы я написал запрос, который бы уменьшал скидку на все продажи (если она есть). Любая помощь высоко ценится.

Комментарии:

1. Похоже, что ваш код VB.NET . Я добавил этот тег, если это неправильно, вы можете это исправить.

Ответ №1:

Это распространенная ошибка LINQ2SQL.

Функция SUM в SQL возвращает значение null, если в коллекции нет элементов, но сигнатура Enumerable.Sum() возвращает значение int. Это приводит к исключению во время выполнения, когда SQL-запрос возвращает null, где поставщик LINQ2SQL ожидает целое число.

Решение состоит в том, чтобы преобразовать результат суммы в целое число с нулевым значением и использовать GetValueOrDefault для преобразования нулевого значения в 0.

Заменить

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

с

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

Ответ №2:

Вы пробовали:

 ...
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
...
  

Комментарии:

1. Я думаю, что код Muthu выглядит следующим образом VB.NET и тернарный оператор произносится IF(Condition, TrueValue, FalseValue) в VB.NET .

2. Да! долгое время привык к кодированию на c #. Этого не заметил. Спасибо.

3. и… null пишется Nothing в VB.NET . Написание VB.NET когда вы привыкли к c #, кажется, что вы вылили на клавиатуру две чашки кофе. Вы просто вводите текст как обычно, но везде получаете красные закорючки.