2011-05-05 41 views
11

Problema simple: Tengo usuarios que pueden tener muchos pedidos que pueden tener muchos productos. ¿Cómo se ve la consulta de Linq (lambda) para obtener el total general de todos los valores de Product.Price?Suma valores anidados con Linq

He intentado esto:

int total = users.Sum(u => u.Orders.Sum(o => o.Products.Sum(p => p.Price))); 

Pero me está dando:

El elenco de tipo de valor 'Int32' falló porque el valor materializado es nulo. O el parámetro genérico del tipo de resultado o la consulta debe usar un tipo anulable.

Por supuesto, un usuario puede no tener ningún pedido, y un pedido puede no tener ningún producto. Pero Product.Price no es un valor que admite valores.

así que he intentado esto, pensando que se estaba ahogando en colecciones vacías:

int total = users.Sum(u => u.Orders.Sum(o => o.Products.Sum(p => p.Price) ?? 0) ?? 0) ?? 0; 

Pero se está lanzando errores de compilación, diciendo que el lado izquierdo de la ?? no es anulable.

¿Qué estoy haciendo mal?

Gracias de antemano.

ACTUALIZACIÓN: Una versión de trabajo de mis ejemplos anteriores después de usar la lógica de Marc de su respuesta:

int total = users.Sum(u => u.Orders.Sum(o => o.Products.Sum(p => (int?)p.Price))) ?? 0; 

Respuesta

29
int total = (from user in users 
      from order in user.Orders 
      from product in order.Products 
      select (int?)product.Price).Sum() ?? 0; 

sería mi oferta; hay un error molesto que SUM en SQL sobre 0 filas es NULL, no 0 - lo anterior funciona alrededor de eso.

o como lambdas (de comentarios):

int total = users.SelectMany(user => user.Orders) 
       .SelectMany(order => order.Products) 
       .Sum(product => (int?)product.Price) ?? 0; 
+0

Gracias, pero hay una versión Lambda, que también funcionaría? –

+0

Uhhh ... u gana .. – V4Vendetta

+0

@Jerad - sure; agregando –