Ошибка приведения к типу значения Int32, поскольку материализованное значение равно нулю - PullRequest
183 голосов
/ 28 июля 2011

У меня есть следующий код.Я получаю сообщение об ошибке:

"Преобразование в тип значения 'Int32' завершилось неудачно, поскольку материализованное значение является нулевым. Либо универсальный параметр типа результата, либо запрос должен использовать тип NULL."

, когда в таблице CreditHistory нет записей.

var creditsSum = (from u in context.User
                  join ch in context.CreditHistory on u.ID equals ch.UserID                                        
                  where u.ID == userID
                  select ch.Amount).Sum();

Как изменить запрос, чтобы он принимал нулевые значения?

Ответы [ 7 ]

315 голосов
/ 28 июля 2011

Запрос 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.

8 голосов
/ 28 июля 2011

Чтобы разрешить пустое поле Amount, просто используйте оператор объединения нулей для преобразования нулей в 0.

var creditsSum = (from u in context.User
              join ch in context.CreditHistory on u.ID equals ch.UserID                                        
              where u.ID == userID
              select ch.Amount ?? 0).Sum();
4 голосов
/ 26 июня 2017

Было это сообщение об ошибке, когда я пытался выбрать из представления.

Проблема заключалась в том, что представление недавно получило несколько новых пустых строк (в столбце SubscriberId), и оно не было обновлено в EDMX (Сначала база данных EF).

Для работы столбца должен быть тип Nullable.

var dealer = Context.Dealers.Where (x => x.dealerCode == dealerCode) .FirstOrDefault();

До обновления представления:

public int SubscriberId { get; set; }

После обновления представления:

public Nullable<int> SubscriberId { get; set; }

Удаление и добавление представления обратно в EDMX сработало.

Надеюсь, это кому-нибудь поможет.

4 голосов
/ 19 декабря 2012

Вы используете функцию aggregate, которая не заставляет элементы выполнять действие, вы должны убедиться, что запрос linq дает некоторый результат, как показано ниже:

var maxOrderLevel =sdv.Any()? sdv.Max(s => s.nOrderLevel):0
2 голосов
/ 20 марта 2017

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

var packesCount = await botContext.Sales.Where(s => s.CustomerId == cust.CustomerId && s.Validated)
                                .SumAsync(s => (int?)s.PackesCount);
                            if(packesCount != null)
                            {
                                // your code
                            }
                            else
                            {
                                // your code
                            }
1 голос
/ 05 апреля 2017

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

var credits = from u in context.User
              join ch in context.CreditHistory 
                  on u.ID equals ch.UserID                                        
              where u.ID == userID
              select ch;

var creditSum= credits.Sum(x => (int?)x.Amount) ?? 0;
0 голосов
/ 04 октября 2017

Получил эту ошибку в Entity Framework 6 с этим кодом во время выполнения:

var fileEventsSum = db.ImportInformations.Sum(x => x.FileEvents)

Обновление от LeandroSoares:

Используйте это для одиночного выполнения:

var fileEventsSum = db.ImportInformations.Sum(x => (int?)x.FileEvents) ?? 0

Оригинал:

Изменился на это, и тогда это сработало:

var fileEventsSum = db.ImportInformations.Any() ? db.ImportInformations.Sum(x => x.FileEvents) : 0;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...