69 votes

Requête Linq avec nullable somme

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()
}

J'ai reçu cette requête, mais il échoue si aucune voix ne sont trouvés à l'exception:

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

Je suppose que c'est parce somme renvoie un int et non nullable int, en donnant la somme d'un int? en entrée seulement de donner la même erreur, probablement à cause de la somme seulement workes sur ints.

Toute bonne solution pour cela?

74voto

Scott Stafford Points 13161

Vous souhaitez utiliser le nullable forme de Somme, alors essayez de lancer votre valeur à un nullable:

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)
}

Votre question est ici abordée plus en détail:

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

22voto

Rashack Points 3344
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 ça... (prise de vue une fois depuis que je ne connais pas votre modèle...):

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) 
}

19voto

Jeroen Bernsen Points 141

En supposant que "v. Points" est une virgule suffit d'utiliser les éléments suivants:

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
}

11voto

Emir Points 923

Si vous n'aimez pas de casting pour nullabe virgule vous pouvez également essayer d'utiliser Linq to Objects avec ToList() la méthode,

LinqToObjects Somme de regroupement vide est 0, où LinqToSql Somme de regroupement vide est nulle.

5voto

Razzie Points 14705

Simple mais efficace, la solution de contournement serait de seulement la somme des voix où les Points.Count > 0, de sorte que vous n'aurez jamais des valeurs null:

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()
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X