Запрос linq-to-sql не выполняется как код, а переводится в SQL.Иногда это «дырявая абстракция», которая приводит к неожиданному поведению.
Одним из таких случаев является обработка пустых значений, когда в разных местах могут возникать неожиданные нулевые значения....DefaultIfEmpty(0).Sum(0)
может помочь в этом (довольно простом) случае, когда элементов может не быть, и sql SUM
возвращает null
, тогда как c # ожидает 0.
Более общий подход заключается в использовании ??
, которыйбудет преобразован в COALESCE
всякий раз, когда существует риск того, что сгенерированный SQL вернет неожиданный нуль:
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 to Entities.