La conversión al tipo de valor ‘Int32’ falló porque el valor materializado es nulo

tengo el siguiente código. Me sale un error:

“Falló la conversión al tipo de valor ‘Int32’ porque el valor materializado es nulo. O el parámetro genérico del tipo de resultado o la consulta deben usar un tipo que admite nulos”.

cuando la tabla CreditHistory no tiene 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(); 

¿Cómo puedo modificar la consulta para aceptar valores nulos?

Una consulta de linq-a-sql no se ejecuta como código, sino que se traduce a SQL. A veces se trata de una “abstracción con fugas” que produce un comportamiento inesperado.

Uno de estos casos es el manejo nulo, donde puede haber nulos inesperados en diferentes lugares. ...DefaultIfEmpty(0).Sum(0) puede ayudar en este caso (bastante simple), donde no puede haber elementos y SUM de sql devuelve null mientras que c # expect 0.

Un enfoque más general es usar ?? que se traducirá a COALESCE siempre que exista el riesgo de que el SQL generado COALESCE un 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; 

Esto primero arroja a int? decirle al comstackdor de C # que esta expresión puede devolver null , aunque Sum() devuelve un int . Entonces usamos el normal ?? operador para manejar el caso null .

En base a esta respuesta, escribí una publicación de blog con detalles para LINQ to SQL y LINQ to Entities.

Para permitir un campo de Amount anulable, simplemente use el operador coalescente nulo para convertir nulos en 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(); 

Está utilizando aggregate función de aggregate que no hace que los elementos realicen una acción, debe verificar que la consulta de linq está dando algún resultado de la siguiente manera:

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

Tenía este mensaje de error cuando estaba intentando seleccionar desde una vista.

El problema era que la vista recientemente había ganado algunas filas nulas nuevas (en la columna SuscriptorId) y no se había actualizado en EDMX (primero en la base de datos de EF).

La columna debe ser de tipo Nullable para que funcione.

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

Antes de ver la actualización:

 public int SubscriberId { get; set; } 

Después de ver la actualización:

 public Nullable SubscriberId { get; set; } 

Eliminar y agregar la vista en EDMX funcionó.

Espero que ayude a alguien.

Me utilizan este código y responde correctamente, solo el valor de salida es anulable.

 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 } 

Veo que esta pregunta ya está respondida. Pero si desea que se divida en dos enunciados, se puede considerar el siguiente.

 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; 

Obtuve este error en Entity Framework 6 con este código en tiempo de ejecución:

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

Actualización de LeandroSoares:

Use esto para una sola ejecución:

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

Original:

Cambiado a esto y luego funcionó:

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