LINQ.SUM() и значения с нулевым значением db

Я знаю, почему это происходит, но может ли кто-нибудь указать мне в правильном направлении синтаксиса?

В настоящее время у меня есть:

var expense = from e in db.I_ITEM
              where e.ExpenseId == expenseId
              select e;

return expense.Sum(x => x.Mileage ?? 0);

Моя проблема в том, что x.Mileage имеет тип "double?" и имеет нулевые значения в db.

Ошибка, которую я получаю:

Exception Details: System.InvalidOperationException: The cast to value type 'Double' failed because the materialized value is null. Either the result type generic parameter or the query must use a nullable type.

Каким будет правильный синтаксис?

Ответ 1

Я удивлен, что это не сработает, но альтернатива, которая может работать, - это просто суммировать значения с нулевым значением, а затем использовать оператор нулевой коалесценции:

return expense.Sum(x => x.Mileage) ?? 0d;

Конечно, в LINQ to Objects это будет делать правильно, игнорируя нулевые значения и давая вам нулевой результат (до оператора нулевой коалесценции), если в последовательности не было ненулевых значений.

Ответ 2

Как насчет исключения нулей, т.е.

var expense = 
          from e in db.I_ITEM
          where (e.ExpenseId == expenseId) && (e.Mileage.HasValue)
          select e;

 return expense.Sum(x => x.Mileage);

Ответ 3

может дать вам мнение...

    decimal depts = 0;

    var query = from p in dc.Payments
                where p.UserID == UserID
                select p.Amount;

    if (query.Count() > 0)
    {
        depts = query.Sum();
    }

    return depts;

Ответ 4

Какой O/R-картограф вы используете, и какую БД вы используете? (Linq to SQL/Entity Framework/SQL Server)?

Поскольку выражение выполняется в БД как оператор SQL, я бы подумал, что он будет работать без оператора коалесценции:

var расход = от e в db.I_ITEM             где e.ExpenseId == costsId             выберите e;

возврат средств. Сумма (x = > x.Mileage);

Ответ 5

var expense = (from e in db.I_ITEM
              where e.ExpenseId == expenseId
              select e.Mileage??0D);
return expense.Sum();

Ответ 6

Обнуляемое поле: если вычисляемое поле обнуляемо, нет необходимости делать что-то особенное. Просто используйте сумму как есть, как показано ниже:

var summation = expense.Sum(x => x.Mileage);

Здесь суммирование обнуляемо (double?). Если вы сделаете его не обнуляемым, используйте оператор объединения нулей и установите значение по умолчанию 0 (ноль), как показано ниже:

var summation = expense.Sum(x => x.Mileage) ?? 0d;

Не обнуляемое поле: но, если вычисляемое поле не может быть обнуляемым, вам необходимо сначала привести к обнуляемому значению для суммирования, как показано ниже:

var summation = expense.Sum(x => (double?)x.Mileage);

Также здесь суммирование можно обнулять (дважды?). Если вы сделаете его не обнуляемым, используйте оператор объединения нулей, как показано ниже:

var summation = expense.Sum(x => (double?)x.Mileage)?? 0d;