Запрос linq-to-sql не выполняется как код, а скорее переведен в SQL. Иногда это «непроницаемая абстракция», которая приводит к неожиданному поведению.
Одним из таких случаев является обработка с нулевым значением, где могут быть неожиданные нули в разных местах. ...DefaultIfEmpty(0).Sum(0)
может помочь в этом (довольно простом) случае, когда не может быть элементов, а sql SUM
возвращает null
, тогда как c # ожидать 0.
. Более общий подход заключается в использовании ??
который будет переведен на COALESCE
всякий раз, когда существует риск того, что сгенерированный SQL вернет неожиданный null:
var creditsSum = (from u in context.User
join ch in context.CreditHistory on u.ID equals ch.UserID
where u.ID == userID
select (int?)ch.Amount).Sum() ?? 0;
Это первое приводит к int?
, чтобы сообщить компилятору C #, что это выражение действительно может вернуться null
, хотя Sum()
возвращает int
. Затем мы используем обычный ??
оператор для обработки случая null
.
Основываясь на этом ответе, я написал сообщение в блоге с подробными сведениями для LINQ to SQL и LINQ для объектов.