Суммируйте вложенные значения с Linq
Простая проблема: у меня есть пользователи, у которых может быть много ордеров, которые могут иметь много продуктов. Как выглядит запрос Linq (лямбда), чтобы получить Пользователь в целом по всем значениям Product.Price?
Я пробовал это:
int total = users.Sum(u => u.Orders.Sum(o => o.Products.Sum(p => p.Price)));
Но это дает мне:
Признак типа "Int32" не выполнен, потому что материализованное значение равно null. Либо общий параметр типа результата, либо запрос должен использовать тип с нулевым значением.
Конечно, у пользователя могут не быть никаких заказов, и у заказа может не быть никаких продуктов. Но Product.Price не является нулевым значением.
Итак, я попробовал это, думая, что он задыхается от пустых коллекций:
int total = users.Sum(u => u.Orders.Sum(o => o.Products.Sum(p => p.Price) ?? 0) ?? 0) ?? 0;
Но он бросает ошибки компиляции, говоря, что левая сторона ??
не имеет значения NULL.
Что я делаю неправильно?
Спасибо заранее.
UPDATE: рабочая версия моих примеров выше после использования логики Marc из его ответа:
int total = users.Sum(u => u.Orders.Sum(o => o.Products.Sum(p => (int?)p.Price))) ?? 0;
Ответы
Ответ 1
int total = (from user in users
from order in user.Orders
from product in order.Products
select (int?)product.Price).Sum() ?? 0;
будет моим предложением; есть раздражающий глюк, что SUM в SQL над 0 строками NULL
, а не 0
- выше это работает.
или как lambdas (из комментариев):
int total = users.SelectMany(user => user.Orders)
.SelectMany(order => order.Products)
.Sum(product => (int?)product.Price) ?? 0;