210 votes

Comment forcer LINQ Sum() à retourner 0 lorsque la collection source est vide ?

En fait, lorsque je fais la requête suivante, si aucune piste n'a été trouvée, la requête suivante lève une exception. Dans ce cas, je préférerais que la somme soit égale à 0 plutôt qu'une exception soit levée. Est-ce que cela serait possible dans la requête elle-même - je veux dire qu'au lieu de stocker la requête et de contrôler query.Any() ?

double earnings = db.Leads.Where(l => l.Date.Day == date.Day
                && l.Date.Month == date.Month
                && l.Date.Year == date.Year
                && l.Property.Type == ProtectedPropertyType.Password
                && l.Property.PropertyId == PropertyId).Sum(l => l.Amount);

433voto

Simon Belanger Points 5480

Essayez de changer votre requête en ceci :

db.Leads.Where(l => l.Date.Day == date.Day
            && l.Date.Month == date.Month
            && l.Date.Year == date.Year
            && l.Property.Type == ProtectedPropertyType.Password
            && l.Property.PropertyId == PropertyId)
         .Select(l => l.Amount)
         .DefaultIfEmpty(0)
         .Sum();

De cette façon, votre requête ne sélectionnera que les éléments suivants Amount champ. Si la collection est vide, elle retournera un élément avec la valeur de 0 et ensuite la somme sera appliquée.

213voto

2kay Points 3690

Je préfère utiliser un autre hack :

double earnings = db.Leads.Where(l => l.Date.Day == date.Day
                                      && l.Date.Month == date.Month
                                      && l.Date.Year == date.Year
                                      && l.Property.Type == ProtectedPropertyType.Password
                                      && l.Property.PropertyId == PropertyId)
                          .Sum(l => (double?) l.Amount) ?? 0;

9voto

Kovács Róbert Points 89

Essayez plutôt ceci, c'est plus court :

db.Leads.Where(..).Aggregate(0, (i, lead) => i + lead.Amount);

4voto

Pedro Ramos Points 41

C'est une victoire pour moi :

int Total = 0;
Total = (int)Db.Logins.Where(L => L.id == item.MyId).Sum(L => (int?)L.NumberOfLogins ?? 0);

Dans ma table LOGIN, dans le champ NUMBEROFLOGINS, certaines valeurs sont NULL et d'autres ont un nombre INT. J'additionne ici le total de NUMBEROFLOGINS de tous les utilisateurs d'une société (chaque Id).

3voto

Maxim Lukoshko Points 51

Essayez :

double gains = db.Leads.Where(l => l.ShouldBeIncluded).Sum(l => (double ?) l.Montant) ? ? 0 ;

La question " SELECT SUM([Montant]) " renverra NULL pour une liste vide. Mais si vous utilisez LINQ, il s'attend à ce que le " Somme(l => l.Montant) "retourne un double et ne vous permet pas d'utiliser " ? ? L'opérateur " " permet de mettre 0 pour une collection vide.

Afin d'éviter cette situation, vous devez faire en sorte que LINQ attende " double ? ". Vous pouvez le faire en lançant " (double ?)l.Montant ".

Cela n'affecte pas la requête en SQL mais cela fait que LINQ fonctionne pour les collections vides.

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