views:

159

answers:

1

I am trying to sum the cost for a series of items grouped by a person's organization. I believe the summation is working correctly but I am not seeing my grouping. The objects stored in rollup just contain the value of the summation. I'd expect them to have the organization in addition to the sum of the cost for that organization. What have I missed in this expression?

var rollup = OrgPersonList.GroupBy(
    person => person.Person.Org).Select(group =>
        group.Sum(price => price.Items.Sum(item =>
            item.Cost)));
+1  A: 

Well you're only selecting the sum - if you want the key as well, you should select that. For example:

var rollup = OrgPersonList.GroupBy(x => x.Person.Org)
    .Select(group => new { group.Key,
                           Sum =group.Sum(x => x.Items.Sum(item => item.Cost))});

Note that I've used x rather than person or price as it seems the same item encapsulates both.

Or as a query expression:

var rollup = from x in OrgPersonList
             group x by x.Person.Org into grouped
             select new { grouped.Key,
                          Sum =grouped.Sum(x => x.Items.Sum(item =>item.Cost))});

(Whitespace somewhat tight for formatting...)

Alternatively again, the group...by could calculate the sum for each entry, so the result just needs to be the sum of the entries in the group:

var rollup = from x in OrgPersonList
             group x.Items.Sum(item => item.Cost) by x.Person.Org into grouped
             select new { grouped.Key, Sum = grouped.Sum() }); 
Jon Skeet
Are the single letter variable names a *style* choice or a teaching mechanism for linq / lambda expressions?
ahsteele
@ahsteele: I had no real information for what the items in an OrgPersonList really are, so it was hard to come up with a better name. Admittedly single letter names are quite handy in LINQ queries *if* they're easily understood. In this case it was more for necessity though - I wanted to be consistent in my uses of the same type (as opposed to using `person` and `price` for the same kind of object).
Jon Skeet
@Jon Is there a performance difference between any of these options or is it a matter of preference?
ahsteele
@ahsteele: I wouldn't like to guess, to be honest. It will partly depend on the context - is this LINQ to Objects, LINQ to SQL, Entity Framework, something else? If performance matters to you, test it.
Jon Skeet
I would suggest compiling all three versions and checking out how they are compiled in Reflector. The first two will be identical; the latter will use different overloads of GroupBy and Sum. The performance difference will be negligible, but the latter adds slightly less overhead because it moves the Sum projection into the GroupBy call, replacing an identity projection. That said, if you're optimizing at that level you probably shouldn't be using LINQ.
dahlbyk
@Jon @dahlbyk Good to know. My question about performance was more out of curiosity than need. Thank you to both of you.
ahsteele