Независимо от того, есть ли у вас одно или несколько значений, не имеет смысла брать первый результат из суммы.
Если у меня 10 человек, я могу найти возраст первого или сумму 100 * * всех из них, но я не могу сначала найти сумма возрастов. Так что вы можете сделать:
var matches = fooList.Where(f => f.Id == 1 || f.Id == 2);
var sum = new FooAmounts { Month1 = matches.Sum(f => f.Month1),
Month2 = matches.Sum(f => f>Month2),
... };
Теперь это будет выполнять запрос несколько раз, конечно. Вместо этого вы можете материализовать запрос, а затем выполнить суммирование по нему:
// Materialize the result so we only filter once
var matches = fooList.Where(f => f.Id == 1 || f.Id == 2).ToList();
var sum = new FooAmounts { Month1 = matches.Sum(f => f.Month1),
Month2 = matches.Sum(f => f>Month2),
... };
Или же вы можете использовать агрегацию:
var sum = fooList.Where(f => f.Id == 1 || f.Id == 2)
.Aggregate(new FooAmounts(), // Seed
(sum, item) => new FooAmounts {
Month1 = sum.Month1 + item.Month1,
Month2 = sum.Month2 + item.Month2,
...
});
Это будет повторять последовательность только один раз, и не будет создавать большой буфер в памяти, но создаст много экземпляров FooAmounts
во время итерации.
Вы могли бы модифицировать аккумулятор на месте, конечно:
var sum = fooList.Where(f => f.Id == 1 || f.Id == 2)
.Aggregate(new FooAmounts(), // Seed
(sum, item) => {
sum.Month1 += item.Month1;
sum.Month2 += item.Month2;
...
return sum;
});
Мне кажется, немного противно, но на самом деле * не имеет побочных эффектов в плохой форме, поскольку это только мутирует объект, который все равно инициализируется в вызове .