2009-08-24 17 views
13

Mam kwerendy LINQ, który wygląda tak ...Jak zrobić zwrot LINQ Suma null, jeśli zsumowanej wartości są wszystkie wartości null

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

Jeśli wszystkie wartości d.DurationMonths są nieważne sumy wraca 0. Jak mogę sprawić, by suma zwracała null, jeśli wszystkie wartości są równe ? Czy muszę najpierw uruchomić osobne zapytanie, aby wyeliminować tę sytuację przed wykonaniem sumy?

+0

Jaki jest typ DurationMonths? int? 'Nullable '? –

+0

DurationMonths is int? –

Odpowiedz

11

Wraz z poprzednią propozycją dla metody rozszerzenie - można użyć operatora potrójny ...

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

Ta kwerenda dwukrotnie wylicza wyniki ... –

+2

Mimo że wylicza ona wyniki dwukrotnie, moje kolekcje są małe i uważam je za najbardziej czytelne. Więc przyjąłem to. Dziękuję wszystkim. –

1

Korzystanie sam Sum, jest to niemożliwe. Jak wskazano w pytaniu, trzeba będzie sprawdzić w tej sytuacji przed wywołaniem Sum:

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

Bah, mniej niż minutę za późno. Lol –

3

Można użyć Aggregate dostarczenie kodu niestandardowego agregacji:

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

(zakładając pozycje w Level3Data są typu D)

+0

'+ =' powinno naprawdę być po prostu '+'. – GSerg

+0

@GSerg, naprawione, dzięki! –

-1

Jeśli chciałbyś wynik bez dwóch zapytań spróbować:

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

Jeśli chcesz zera zamiast null jako rezultat zastosowania tej kwerendy.

var czas = Level3Data.AsQueryable() Sum (? D => (podwójne) d.DurationMonths) ?? 0;

+0

Ja osobiście najbardziej lubię tę opcję. – TravisWhidden

+3

Jeśli ['DurationMonths' to' int? '] (Http://stackoverflow.com/questions/1322544/how-to-make-a-linq-sum-return-null- if-to-ed-values-are -all-null # comment1156228_1322544) a wszystkie wartości to 'null', Linq2Sql zwróci' null' dla 'Sum', a Linq2Objects zwróci' 0'. OP ma zwrócone '0', więc używają Linq2Objects, w takim przypadku casting do' double? 'Przed podsumowaniem [nie zadziała] (http://stackoverflow.com/questions/1322544/how-to-make- a-linq-sum-return-null-jeśli-zsumowane-wartości-są-wszystkie-null # comment69281108_16441725), a wynikiem będzie nadal "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; 

Można jawnie typu non-cast zerowalne varaible do wartości pustych typu. i.e, select (int?)OutputIndicatorTable.Status).Sum();

+1

Ta odpowiedź jest błędna. Przesyłanie do '(int?)' Przed podsumowaniem ma sens w kontekście Linq2Sql, gdzie 'Sum' może zwrócić' null' (bezpośrednio z zapytania SQL) nawet wtedy, gdy kompilator podaje wynik nie-nulla, który prowadzi do wyjątku. W Linq2Objects 'Sum' zawsze zwraca' 0', nawet jeśli wszystkie elementy wejściowe miały wartość 'null' lub nie zawierały żadnych elementów wejściowych. – GSerg

Powiązane problemy