2009-08-24 21 views
13

Tengo una consulta LINQ que se parece a esto ...Cómo hacer un retorno LINQ Suma nula si los valores sumados son todos nulos

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

Si todos los valores son nulos d.DurationMonths la Suma devuelve 0. ¿Cómo puedo hacer que la suma devuelva null si todos los d.DurationMonths son null? ¿O necesito ejecutar primero una consulta separada para eliminar esta situación antes de realizar la suma?

+0

¿Cuál es el tipo de DuraciónMedios? En t ? 'Nullable '? –

+0

DurationMonths is int? –

Respuesta

11

Junto con la sugerencia anterior de un método de extensión - se puede utilizar un operador ternario ...

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

Esta consulta enumera los resultados dos veces ... –

+2

Aunque esto enumera los resultados dos veces, Mis colecciones son pequeñas y creo que esta es la más legible. Entonces lo he aceptado. Gracias a todos. –

1

Usando Suma solo, esto es imposible. Como se indicó en su pregunta, usted tendrá que comprobar para esta situación antes de llamar Suma:

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

Bah, menos de un minuto, demasiado tarde. Lol –

3

Puede utilizar Aggregate para proporcionar código de agregación personalizada:

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

(suponiendo que los elementos de Level3Data son del tipo D)

+0

El '+ =' realmente debería ser solo '+'. – GSerg

+0

@GSerg, arreglado, ¡gracias! –

-1

Si desea que el resultado sin tratar dos consultas:

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

Si desea cero en lugar de null como resultado de este uso consulta:.

duración var = Level3Data.AsQueryable() Suma (? D => (doble) d.DurationMonths) ?? 0;

+0

A mí personalmente me gusta más esta opción. – TravisWhidden

+3

Si ['DurationMonths'' es' int? '] (Http://stackoverflow.com/questions/1322544/how-to-make-a-linq-sum-return-null-if-the-summed-values-are -all-null # comment1156228_1322544) y todos los valores son 'null', Linq2Sql devolverá' null' para 'Sum', y Linq2Objects devolverá' 0'. El OP ha devuelto el '0 ', por lo que están utilizando Linq2Objects, en cuyo caso el fundido en' double? 'Antes de sumar [no funcionará] (http://stackoverflow.com/questions/1322544/how-to-make- a-linq-sum-return-null-if-the-summed-values-are-all-null # comment69281108_16441725) y el resultado seguirá siendo '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; 

Puede escribir explícitamente el valor de cast no-nullable varaible en el tipo de nulo. i.e, select (int?)OutputIndicatorTable.Status).Sum();

+1

Esta respuesta es incorrecta. Casting a '(int?)' Antes de sumar tiene sentido en el contexto de Linq2Sql, donde 'Suma' puede devolver' null' (directamente de la consulta SQL) incluso cuando el compilador infiere un resultado que no admite nulos que da lugar a una excepción. Con Linq2Objects, 'Suma 'siempre devuelve' 0' incluso si todos los elementos de entrada eran 'nulos' o no había elementos de entrada en absoluto. – GSerg

Cuestiones relacionadas