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 erhalten, die jedoch fehlschlägt, 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 aus, dass weil die Summe ein int und kein nullbares int zurückgibt, was der Summe ein int ergibt. da die eingabe nur den gleichen fehler ergibt, wirkt sich die summe nur auf ints aus.
Gibt es eine gute Lösung für dieses Problem?
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()
}
BEARBEITEN - ok was ist damit ... (Nochmal schießen, da ich dein Modell nicht kenne ...):
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)
}
Sie möchten die nullfähige Form von Sum verwenden. Versuchen Sie daher, Ihren Wert in eine nullfähige umzuwandeln:
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 ausführlicher besprochen:
Angenommen, "v.Points" ist eine Dezimalzahl, verwenden Sie einfach Folgendes:
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 keine Umwandlung in nullabe decimal möchten, können Sie auch die Linq To Objects-Methode mit ToList () verwenden.
LinqToObjects Summe der leeren Auflistung ist 0, wobei LinqToSql Summe der leeren Auflistung null ist.
Versuchen Sie dies herauszufinden:
var count = db.Cart.Where(c => c.UserName == "Name").Sum(c => (int?)c.Count) ?? 0;
Die Ursache des Problems ist also, dass die SQL-Abfrage folgendermaßen lautet:
SELECT SUM([Votes].[Value])
FROM [dbo].[Votes] AS [Votes]
WHERE 1 = [Votes].[UserId]
gibt NULL zurück
Eine einfache, aber effektive Problemumgehung wäre, nur die Stimmen zu summieren, bei denen Punkte.Zahl> 0 ist, sodass Sie niemals Nullwerte 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()
}
Nur um eine weitere Methode in die Mischung einzufügen :)
Where(q=> q.ItemId == b.ItemId && b.Points.HasValue).Sum(q=>q.Points.Value)
Ich hatte ein ähnliches Szenario, habe aber beim Summieren kein zusätzliches Feld verglichen ...
Where(q => q.FinalValue.HasValue).Sum(q=>q.FinalValue.Value);
Das Annehmen von Punkten ist eine Liste von Int32.
var sum = Points.DefaultIfEmpty().Sum(c => (Int32)c ?? 0)
Ich denke, das ist der gleiche Fall ... Ich habe es gelöst. Das 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 diese Hilfe.
Ich hatte das gleiche Problem. Mit leerer Listenvereinigung gelöst:
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()
}
Wenn "Punkte" eine Ganzzahl ist, sollte dies funktionieren.
Diese Abfrage könnte in try/catch..if gesetzt sein, wenn keine Ausnahme gefunden wurde
Ähnlich wie die vorherigen Antworten, Sie können aber auch das Ergebnis der gesamten Summe in den Typ mit Nullwert umwandeln.
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
}
Das passt wohl besser zu dem, was wirklich vor sich geht, aber es hat den gleichen Effekt wie der Cast in diese Antwort .
(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);
Das funktioniert, ist aber nicht sehr hübsch oder lesbar.
Ich dachte, ich würde eine andere Lösung da draußen werfen. Ich hatte ein ähnliches Problem und so habe ich das Problem gelöst:
Where(a => a.ItemId == b.ItemId && !b.IsPointsNull()).Sum(b => b.Points)
Ich hatte ein ähnliches Problem und kam zu der Lösung, alles, was ich versuchte, aus der Datenbank zu bekommen, zu zählen, auf diese zu zählen und nur dann, wenn ich etwas zurückbekommen hatte, eine Summe zu machen. War nicht in der Lage, die Besetzung aus irgendeinem Grund zum Laufen zu bringen, so dass dies veröffentlicht wird, wenn andere Personen ähnliche Probleme hatten.
z.B.
Votes = (from v in Db.Votes
where b.ItemId = v.ItemId
select v)
Überprüfen Sie dann, ob Sie Ergebnisse erhalten, sodass keine Nullwerte zurückgegeben werden.
If (Votes.Count > 0) Then
Points = Votes.Sum(Function(v) v.Points)
End If