2009-08-24 14 views
13

ho una query LINQ che assomiglia a questo ...Come fare un ritorno LINQ Somma nullo se i valori sommati sono tutti nulli

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

Se tutti i valori sono nulli d.DurationMonths Somma restituisce 0. Come posso rendere il Somma restituire null se tutti gli d.DurationMonths sono null? O devo prima eseguire una query separata per eliminare questa situazione prima di eseguire la somma?

+0

Qual è il tipo di DurataMesi? int? 'Nullable '? –

+0

DurationMonths è int? –

risposta

11

Insieme con la precedente proposta di un metodo di estensione - è possibile utilizzare un operatore ternario ...

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

Questa query enumera i risultati due volte ... –

+2

Anche se questo enumera i risultati due volte, Le mie raccolte sono piccole e trovo questo il più leggibile. Quindi l'ho accettato. Grazie a tutti. –

1

Utilizzando Somma da sola, questo è impossibile. Come hai indicato nella domanda, è necessario verificare la presenza di questa situazione prima di chiamare Somma:

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

Bah, meno di un minuto troppo tardi. Lol –

3

È possibile utilizzare Aggregate di fornire il codice di aggregazione personalizzato:

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

(supponendo che le voci in Level3Data sono di tipo D)

+0

'+ =' dovrebbe essere solo '+'. – GSerg

+0

@GSerg, risolto, grazie! –

-1

Se si desidera che il risultato senza provare due query:

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

Se volete zero invece di null come risultato di questo uso query:.

var = durata Level3Data.AsQueryable() Somma (? D => (doppio) d.DurationMonths) ?? 0;

+0

Personalmente mi piace di più questa opzione. – TravisWhidden

+3

Se ['DurationMonths' è' int? '] (Http://stackoverflow.com/questions/1322544/how-to-make-a-linq-sum-return-null-if-the-summed-values-are -all-null # comment1156228_1322544) e tutti i valori sono 'null', Linq2Sql restituirà' null' per 'Sum', e Linq2Objects restituirà' 0'. L'OP ha restituito il valore '0', quindi stanno utilizzando Linq2Objects, nel qual caso il cast è' double? 'Prima di sommare [non funziona] (http://stackoverflow.com/questions/1322544/how-to-make- a-linq-sum-return-null-if-the-summed-values-are-all-null # comment69281108_16441725) e il risultato sarà ancora '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; 

È possibile digitare in modo esplicito la variabile non nullable cast in tipo nullable. i.e, select (int?)OutputIndicatorTable.Status).Sum();

+1

Questa risposta è sbagliata. Eseguire il cast di '(int?)' Prima che la somma abbia senso nel contesto di Linq2Sql, dove 'Sum' può restituire' null' (direttamente dalla query SQL) anche quando il compilatore deduce un risultato non nullable che porta a un'eccezione. Con Linq2Objects, 'Sum' restituisce sempre' 0' anche se tutti gli elementi di input erano 'null' o non c'erano affatto elementi di input. – GSerg

Problemi correlati