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?

War es hilfreich?

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:

http://weblogs.asp.net/zeeshanhirani/archive/2008/07/15/applying-aggregates-to-empty-collections-causes-exception-in-linq-to-sql. aspx

"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)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top