2009-08-24 8 views
13

J'ai une requête LINQ qui ressemble à ceci ...Comment faire un retour Somme LINQ null si les valeurs sommées sont toutes nulles

var duration = Level3Data.AsQueryable().Sum(d => d.DurationMonths); 

Si toutes les valeurs sont nulles d.DurationMonths la somme retourne 0. Comment puis-je faire la somme Retour null si tous les d.DurationMonths sont null? Ou dois-je d'abord lancer une requête séparée pour éliminer cette situation avant d'effectuer la somme?

+0

Quel est le type de DurationMonths? int? 'Nullable '? –

+0

DurationMonths est int? –

Répondre

11

Avec la suggestion précédente pour une méthode d'extension - vous pouvez utiliser un opérateur ternaire ...

var duration = Level3Data.AsQueryable().Any(d => d.DurationMonths.HasValue) 
       ? Level3Data.AsQueryable().Sum(d => d.DurationMonths) 
       : null; 
+6

Cette requête énumère les résultats deux fois ... –

+2

Bien que cela énumère les résultats deux fois, Mes collections sont petites et je trouve cela le plus lisible. Alors l'ai accepté. Merci tout le monde. –

1

L'utilisation seule somme, cela est impossible. Comme vous l'avez indiqué dans votre question, vous devez vérifier cette situation avant d'appeler Somme:

var q = Level3Data.AsQueryable(); 
var duration = q.All(d => d.DurationMonths == null) 
        ? null 
        : q.Sum(d => d.DurationMonths); 
+0

Bah, moins d'une minute trop tard. Lol –

3

Vous pouvez utiliser Aggregate pour fournir le code d'agrégation personnalisé:

var items = Level3Data.AsQueryable(); 
var duration = items.Aggregate<D,int?>(null, (s, d) => (s == null) ? d.DurationMonths : s + (d.DurationMonths ?? 0)); 

(en supposant que les éléments en Level3Data sont de type D)

+0

Le '+ =' devrait vraiment être simplement '+'. – GSerg

+0

@GSerg, fixe, merci! –

-1

Si vous voulez le résultat sans deux requêtes essayer:

var duration = Level3Data.AsQueryable(). Somme (d => (double?) D.DurationMonths);

Si vous voulez zéro au lieu de null à la suite de cette utilisation de la requête:.

var durée = Level3Data.AsQueryable() Somme (?; D => (double) d.DurationMonths) ?? 0;

+0

Personnellement, j'aime cette option. – TravisWhidden

+3

Si ['DurationMonths' est' int? '] (Http://stackoverflow.com/questions/1322544/how-to-make-a-linq-sum-return-null-if-the-summed-values-are -all-null # comment1156228_1322544) et toutes les valeurs sont 'null', Linq2Sql retournera' null' pour 'Sum', et Linq2Objects retournera' 0'. L'OP a le '0' retourné, donc ils utilisent Linq2Objects, dans ce cas, la conversion en' double? 'Avant la sommation [ne fonctionnera pas] (http://stackoverflow.com/questions/1322544/how-to-make- a-linq-sum-return-null-si-les-valeurs-additionnées-sont-tout-null # comment69281108_16441725) et le résultat sera toujours '0'. – GSerg

3
var outputIndicatorSum = (from OutputIndicatorTable in objDataBaseContext.Output_Indicators 
              where OutputIndicatorTable.Output_Id == outputId 
              select (int?)OutputIndicatorTable.Status).Sum(); 
       int outputIndicatorSumReturn = Convert.ToInt32(outputIndicatorSum); 
       return outputIndicatorSumReturn; 

Vous pouvez explicitement taper cast varaible non-nullable en type nullable. i.e, select (int?)OutputIndicatorTable.Status).Sum();

+1

Cette réponse est fausse. La conversion en '(int?)' Avant la sommation est logique dans le contexte de Linq2Sql, où 'Sum' peut renvoyer' null' (directement à partir de la requête SQL) même si le compilateur déduit un résultat non nul qui conduit à une exception. Avec Linq2Objects, 'Sum' renvoie toujours' 0' même si tous les éléments d'entrée étaient 'null' ou s'il n'y avait aucun élément d'entrée. – GSerg

Questions connexes