suma funcion framework column c# linq linq-to-sql sum nullable

c# - funcion - Consulta de Linq con suma anulable



suma linq c# (15)

from i in Db.Items select new VotedItem { ItemId = i.ItemId, Points = (from v in Db.Votes where b.ItemId == v.ItemId select v.Points).Sum() }

Recibí esta consulta, sin embargo, falla si no se encuentran votos con excepción:

The null value cannot be assigned to a member with type System.Int32 which is a non-nullable value type.

Supongo que es porque suma devuelve un int y no una int nullable, dando suma un int? como entrada solo da el mismo error, probablemente causa suma solo trabajos en ints.

¿Alguna buena solución para esto?


Asumir puntos es una lista de Int32, ¿qué tal algo así como:

var sum = Points.DefaultIfEmpty().Sum(c => (Int32)c ?? 0)


Creo que este es el mismo caso. Lo resolví Esta es mi solución:

var x = (from a in this.db.Pohybs let sum = (from p in a.Pohybs where p.PohybTyp.Vydej == true select p.PocetJednotek).Sum() where a.IDDil == IDDil && a.PohybTyp.Vydej == false && ( ((int?)sum??0) < a.PocetJednotek) select a);

Espero esta ayuda.


Desea utilizar la forma Nullable de Sum, así que intente convertir su valor en un valor nulo:

from i in Db.Items select new VotedItem { ItemId = i.ItemId, Points = (from v in Db.Votes where b.ItemId == v.ItemId select v.Points).Sum(r => (decimal?) r.Points) }

Su problema se analiza aquí con más detalle:

weblogs.asp.net/zeeshanhirani/archive/2008/07/15/…


Pensé que lanzaría otra solución por ahí. Tuve un problema similar y así es como terminé resolviéndolo:

Where(a => a.ItemId == b.ItemId && !b.IsPointsNull()).Sum(b => b.Points)


Puede ser para poner esta consulta en try / catch..if "exception", luego no se encontraron votos


Si no te gusta transmitir a nullabe decimal, también puedes intentar usar el método Linq To Objects with ToList (),

LinqToObjects La suma de la colección vacía es 0, donde LinqToSql La suma de la colección vacía es nula.


Similar a las respuestas anteriores, pero también puede convertir el resultado de la suma total al tipo que admite nulos.

from i in Db.Items select new VotedItem { ItemId = i.ItemId, Points = (decimal?)((from v in Db.Votes where b.ItemId == v.ItemId select v.Points).Sum()) ?? 0 }

Podría decirse que esto se ajusta mejor a lo que realmente está sucediendo, pero tiene el mismo efecto que el elenco en esta respuesta .


Solo para agregar otro método a la mezcla :)

Where(q=> q.ItemId == b.ItemId && b.Points.HasValue).Sum(q=>q.Points.Value)

Tenía un escenario similar pero no estaba comparando un campo adicional al sumar ...

Where(q => q.FinalValue.HasValue).Sum(q=>q.FinalValue.Value);


Suponiendo que "v.Points" es un decimal, solo use lo siguiente:

from i in Db.Items select new VotedItem { ItemId = i.ItemId, Points = (from v in Db.Votes where b.ItemId == v.ItemId select (decimal?) v.Points).Sum() ?? 0 }


Trata de verificar esto:

var count = db.Cart.Where(c => c.UserName == "Name").Sum(c => (int?)c.Count) ?? 0;

Entonces, la raíz del problema es esa consulta SQL así:

SELECT SUM([Votes].[Value]) FROM [dbo].[Votes] AS [Votes] WHERE 1 = [Votes].[UserId]

devuelve NULL


Tuve un problema similar y se me ocurrió la solución de obtener todo lo que estaba tratando de obtener de la base de datos, hacer un recuento de esos y solo si me devolvía algo, haga una suma. No fue posible hacer funcionar al elenco por algún motivo, por lo que se publicó esto si alguien más tenía problemas similares.

p.ej

Votes = (from v in Db.Votes where b.ItemId = v.ItemId select v)

Y luego verifique si tiene algún resultado para que no se devuelva nulo.

If (Votes.Count > 0) Then Points = Votes.Sum(Function(v) v.Points) End If


Una solución simple pero efectiva sería solo sumar los votos donde Points.Count> 0, por lo que nunca tendrá valores nulos:

from i in Db.Items select new VotedItem { ItemId = i.ItemId, Points = (from v in Db.Votes where b.ItemId == v.ItemId && v.Points.Count > 0 select v.Points).Sum() }


Yo tuve el mismo problema. Lo resolvió con la unión de la lista vacía:

List<int> emptyPoints = new List<int>() { 0 }; from i in Db.Items select new VotedItem { ItemId = i.ItemId, Points = (from v in Db.Votes where b.ItemId == v.ItemId select v.Points).Union(emptyPoints).Sum() }

En el caso de "Puntos" es un número entero, esto debería funcionar.


(from i in Db.Items where (from v in Db.Votes where i.ItemId == v.ItemId select v.Points).Count() > 0 select new VotedItem { ItemId = i.ItemId, Points = (from v in Db.Items where i.ItemId == v.ItemId select v.Points).Sum() }).Union(from i in Db.Items where (from v in Db.Votes where i.ItemId == v.ItemId select v.Points).Count() == 0 select new VotedItem { ItemId = i.ItemId, Points = 0 }).OrderBy(i => i.Points);

Esto funciona, pero no es muy bonito ni legible.


from i in Db.Items select new VotedItem { ItemId = i.ItemId, Points = (from v in Db.Votes where b.ItemId == v.ItemId select v.Points ?? 0).Sum() }

EDITAR - vale, ¿qué pasa con esto ... (Disparando de nuevo ya que no conozco tu modelo ...):

from i in Db.Items select new VotedItem { ItemId = i.ItemId, Points = (from v in Db.Votes where b.ItemId == v.ItemId) .Sum(v => v.Points) }