Общий параметр ошибки Linq или запрос должен использовать тип, допускающий значение NULL.

Я получил эту ошибку, когда использую функцию суммы в LINQ:

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

GroupProduct.Where(a => a.Product.ProductID==1).Sum(Content => Content.Amount==null?0:Content.Amount),

person malik    schedule 16.01.2010    source источник
comment
Каков тип данных свойства Amount?   -  person AnthonyWJones    schedule 16.01.2010
comment
DefaultIfempty является обязательным для использования в случае, если Where не возвращает никакого значения, таким образом избегая NULL в этом случае.   -  person baHI    schedule 11.09.2018


Ответы (5)


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

GroupProduct.Where(a => a.Product.ProductID == 1)
    .Select(c => c.Amount ?? 0) // select only the amount field
    .DefaultIfEmpty()  // if selection result is empty, return the default value
    .Sum(c => c)

DefaultIfEmpty() возвращает значение по умолчанию, связанное с типом Amount, которое равно int, и в этом случае значение по умолчанию равно 0.

person mendel    schedule 11.07.2012
comment
@Sнаджошƒаӽ: спасибо за исправление опечаток в моем ответе. НО я вернул оператор объединения null. DefaultIfEmpty вернет одну запись 0, ТОЛЬКО ЕСЛИ начальный результирующий набор пуст. Если он не пуст, но сумма имеет значение NULL и имеет нулевое значение, он не будет работать без оператора объединения с нулевым значением. - person mendel; 06.03.2017

Вы пробовали следующее:

GroupProduct.Where(a => a.Product.ProductID==1).Sum(Content => (decimal?)Content.Amount)

Код из моего приложения выглядит так:

var data = query.AsEnumerable().Select(row => TaskInfo.FetchTaskInfo(row,
      ctx.ObjectContext.Hours.Where(hour => hour.TaskId == row.TaskId).Sum(hour => (decimal?)hour.Duration),
      ctx.ObjectContext.Notes.Count(note => note.SourceType == (int)SourceType.Task && note.SourceId == row.TaskId)));
person mattruma    schedule 02.03.2011
comment
DefaultIfEmpty перед Sum является обязательным, если на 1-м месте нет возвращенного элемента. - person baHI; 11.09.2018

Вы могли бы исключить источник?

var sum = GroupProduct.Where(a => a.Product.ProductID==1 && a.Amount != null)
            .Sum(a => (decimal)a.Amount);
person Marc Gravell    schedule 16.01.2010
comment
@malik - я не понимаю; можешь перефразировать этот комментарий? - person Marc Gravell; 16.01.2010
comment
Еще раз спасибо: есть две вещи. когда я использую a.Product.ProductID, объект имеет значение null, могу ли я проверить его в запросе linq. - person malik; 16.01.2010
comment
Я имею в виду, что в лямбда-выражении я могу загрузить ссылку и могу ли я обработать нуль в запросе linq. - person malik; 16.01.2010

Попробуй это:

var sum = GroupProduct.Where(a => a.Product.ProductID==1).Sum(Content => (int?) Content.Amount);
sum = sum ?? 0;
person amiry jd    schedule 17.07.2011
comment
Да, это еще один способ решить проблему, разрешив типы, допускающие значение NULL, внутри LINQ и объединив NULL в конце. IMO, DefaultIfEmpty - правильное решение, потому что мы ожидаем число в качестве результата в конце, а не результат, допускающий значение NULL. - person baHI; 11.09.2018

Это выглядит так, как будто оно должно работать (и обычно работает), но не работает, когда метод Where() возвращает значение null:

decimal sum1 = GroupProduct
    .Where(a => a.Product.ProductID == 1)
    .Sum(c => c.Amount ?? 0);

Ошибка: "The cast to value type 'Decimal' failed because the materialized value is null" связана с тем, что метод Sum() возвращает null (не ноль) при суммировании пустого набора.

Любой из них работает для меня:

decimal? sum2 = GroupProduct
    .Where(a => a.Product.ProductID == 1)
    .Sum(c => c.Amount);

decimal sum3 = GroupProduct
    .Where(a => a.Product.ProductID == 1)
    .Sum(c => c.Amount) ?? 0;
person Merenzo    schedule 17.01.2011
comment
DefaultIfEmpty перед Sum является обязательным, если на 1-м месте нет возвращенного элемента. - person baHI; 11.09.2018