Linq Abfrage mit nullable Summe
-
22-08-2019 - |
Frage
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()
}
Ich habe diese Abfrage, aber es schlägt fehl, wenn keine Stimmen mit Ausnahme gefunden werden:
The null value cannot be assigned to a member with type System.Int32 which is a non-nullable value type.
Ich gehe davon sein, weil Summe einen int zurückgibt und kein Nullable-int, was Summe ein int? als nur der Eingang den gleichen Fehler geben, die wahrscheinlich dazu führen, nur Summe auf Ints workes.
Jede gute Abhilfe für dieses?
Lösung
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()
}
EDIT - ok, was dazu ... (Schießen wieder da ich Ihr Modell nicht wissen ...):
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)
}
Andere Tipps
Sie möchten die Nullable-Form Summe verwenden, so versuchen Sie Wert auf einen Nullable-Casting:
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)
}
Ihr Problem wird hier näher erläutert:
"v.Points" Unter der Annahme ist eine Dezimalzahl benutzen Sie einfach die folgenden:
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
}
Wenn Sie Casting nicht wie Sie auch auf nullabe dezimal könnte mit Linq To Objekte mit ToList () Methode versuchen,
LinqToObjects Summe der leeren Sammlung ist 0, wobei LinqToSql Summe der leeren Auflistung ist null.
Versuchen Sie, diese zu überprüfen:
var count = db.Cart.Where(c => c.UserName == "Name").Sum(c => (int?)c.Count) ?? 0;
Die Wurzel des Problems ist also, dass SQL-Abfrage wie folgt aus:
SELECT SUM([Votes].[Value])
FROM [dbo].[Votes] AS [Votes]
WHERE 1 = [Votes].[UserId]
NULL zurück
Eine einfache, aber effektive Abhilfe wäre, nur die Stimmen zusammenzufassen, wo Points.Count> 0, so dass Sie nie null Werte haben:
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()
}
Sie einfach ein weiteres Verfahren in die Mischung hinzufügen:)
Where(q=> q.ItemId == b.ItemId && b.Points.HasValue).Sum(q=>q.Points.Value)
Ich hatte ein ähnliches Szenario, aber ich war nicht ein zusätzliches Feld zu vergleichen, wenn Summieren ...
Where(q => q.FinalValue.HasValue).Sum(q=>q.FinalValue.Value);
Unter der Annahme Punkten wird eine Liste des Int32, wie sei es so etwas wie:
var sum = Points.DefaultIfEmpty().Sum(c => (Int32)c ?? 0)
Ich hatte das gleiche Problem. Gelöst es mit leerer Liste Union:
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()
}
Bei "Punkten" ist integer dies funktionieren soll.
Ich denke, dies ist der gleiche Fall ist. Ich beschloß es. Dies ist meine Lösung:
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);
Ich hoffe, dass diese Hilfe.
(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);
Dies funktioniert, aber ist nicht sehr hübsch oder lesbar ist.
ich ein ähnliches Problem hatte und kam mit der Lösung bis zu bekommen, was ich aus der Datenbank zu erhalten versuche, tut eine Zählung auf diejenigen, und dann auch nur, wenn ich etwas hatte zurück eine Summe tun. War die Besetzung arbeiten aus irgendeinem Grund dies nicht in der Lage zu bekommen, so veröffentlichen, ob jemand ähnliche Probleme hatten.
z.
Votes = (from v in Db.Votes
where b.ItemId = v.ItemId
select v)
Und dann überprüfen, um zu sehen, wenn Sie irgendwelche Ergebnisse haben, so dass Sie nicht bekommen, null zurückgegeben.
If (Votes.Count > 0) Then
Points = Votes.Sum(Function(v) v.Points)
End If
Ähnlich wie in früheren Antworten, aber Sie können werfen auch das Ergebnis der gesamten Summe auf den Nullable Type.
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
}
Die wohl das besser passt, was wirklich los ist, aber es hat die gleiche Wirkung wie die Besetzung in diese Antwort .
Dachte ich eine andere Lösung werfen würde da draußen. Ich hatte ein ähnliches Problem, und das ist, wie ich es am Ende zu lösen:
Where(a => a.ItemId == b.ItemId && !b.IsPointsNull()).Sum(b => b.Points)