A conversão para o tipo de valor ‘Int32’ falhou porque o valor materializado é nulo

Eu tenho o seguinte código. Estou recebendo erro:

“A conversão para o tipo de valor ‘Int32’ falhou porque o valor materializado é nulo. O parâmetro genérico do tipo de resultado ou a consulta deve usar um tipo anulável.”

quando a tabela CreditHistory não tem registros.

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(); 

Como posso modificar a consulta para aceitar valores nulos?

Uma consulta linq-para-sql não é executada como código, mas traduzida em SQL. Às vezes isso é uma “abstração gotejante” que produz um comportamento inesperado.

Um desses casos é o tratamento de nulo, onde pode haver nulos inesperados em locais diferentes. ...DefaultIfEmpty(0).Sum(0) pode ajudar nesse caso (bastante simples), onde pode não haver elementos e o SUM de sql retorna null enquanto c # espera 0.

Uma abordagem mais geral é usar ?? que será traduzido para COALESCE sempre que houver um risco de que o SQL gerado retorne um nulo inesperado:

 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; 

Este primeiro lança para int? para informar o compilador C # que essa expressão pode, de fato, retornar null , mesmo que Sum() retorne um int . Então nós usamos o normal ?? operador para lidar com o caso null .

Com base nessa resposta, escrevi uma postagem no blog com detalhes de LINQ to SQL e LINQ to Entities.

Para permitir um campo Amount anulável, basta usar o operador de coalescência nulo para converter valores nulos em 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(); 

Você está usando aggregate function aggregate que não está recebendo os itens para executar a ação, você deve verificar se a consulta do linq está dando algum resultado como abaixo:

 var maxOrderLevel =sdv.Any()? sdv.Max(s => s.nOrderLevel):0 

Teve essa mensagem de erro quando eu estava tentando selecionar de uma exibição.

O problema é que a visualização recentemente ganhou algumas novas linhas nulas (na coluna SubscriberId) e não foi atualizada no EDMX (database EF primeiro).

A coluna tinha que ser do tipo anulável para funcionar.

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

Antes de ver a atualização:

 public int SubscriberId { get; set; } 

Após a atualização da exibição:

 public Nullable SubscriberId { get; set; } 

Excluindo e adicionando a visão de volta no EDMX funcionou.

Espero que ajude alguém.

Eu usei este código e responde corretamente, apenas o valor de saída é anulável.

 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 } 

Eu vejo que esta questão já foi respondida. Mas se você quiser que seja dividido em duas declarações, o seguinte pode ser considerado.

 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; 

Obteve este erro no Entity Framework 6 com este código em tempo de execução:

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

Atualização de LeandroSoares:

Use isso para execução única:

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

Original:

Mudou para isso e então funcionou:

 var fileEventsSum = db.ImportInformations.Any() ? db.ImportInformations.Sum(x => x.FileEvents) : 0;