Getting the sum of a value in Linq
-
05-07-2019 - |
Question
Given the following structure...
class Foo {
public string Category { get; set; }
public string Code { get; set; }
public int Quantity { get; set; }
}
I am trying to use Linq to summarise a list of these objects by Category and Code, so that if I provide the following source...
List<Foo> foos = new List<Foo>() {
new Foo {Category = @"A", Code = @"B", Quantity = 1},
new Foo {Category = @"A", Code = @"B", Quantity = 2},
new Foo {Category = @"C", Code = @"D", Quantity = 3},
new Foo {Category = @"C", Code = @"D", Quantity = 4}
};
I end up with a list containing...
Foo {Category = @"A", Code = @"B", Quantity = 3},
Foo {Category = @"C", Code = @"D", Quantity = 7}
(where Quantity is the sum of the original quantities of matching objects).
I know I need to use a combination of the group by
clause and the Sum()
extension methods, I just do not seem to be able to find that correct combination.
Please note, there is no database behind this list, I am doing this purely with objects so extracting the original list including the sum is not an option.
Thanks.
Solution
var query = foos
.GroupBy(x => new { x.Category, x.Code })
.Select(g => new Foo
{
Category = g.Key.Category,
Code = g.Key.Code,
Quantity = g.Sum(x => x.Quantity)
});
OTHER TIPS
You want to group by both the category and the code, so you'll want an anonymous type for that - then just sum the quantities. You can do this in a single call to GroupBy
if you use the right overload:
var query = list.GroupBy(
item => new { item.Category, item.Code },
(key, group) => new Foo { Category = key.Category,
Code = key.Code,
Quantity = group.Sum(x => x.Quantity) });
If you want to do this with a query expression, you can use:
var query = from item in list
group item by new { item.Category. item.Code } into items
select new Foo { Category = items.Key.Category,
Code = items.Key.Code,
Quantity = items.Sum(x => x.Quantity) });
LINQ Merging results in rows is very similar:-
var result = foos
.GroupBy( foo => new
{
foo.Category,
foo.Code
} )
.Select( fooGroup => new Foo
{
Category = fooGroup.Key.Category,
Code = fooGroup.Key.Code,
Quantity = fooGroup.Sum( foo => foo.Quantity )
} );