tags:

views:

37

answers:

1

Hi everyone,

I want to use LINQ to group data from a DataTable (columns: userid, chargetag, charge).

The content could look like this:

userid    chargetag    charge
-----------------------------
user1     tag3         100
user2     tag3         100
user3     tag5         250

I need something like this as a result:

chargetag    count    sum
-------------------------
tag3         2        200
tag5         1        250

This is what I have so far:

var groupedData = from b in dataTable.AsEnumerable()
                  group b by b.Field<string>("chargetag") into g
                  let count = g.Count()
                  select new
                  {
                      ChargeTag = g.Key,
                      Count = count,
                  };

I can extract the name of the chargetag and the number of it. How would I have to change the LINQ query to access the sum of charges as well?

Thanks in advance :-)

Regards, Kevin

+7  A: 

That's pretty easy - just use the Sum extension method on the group.

var groupedData = from b in dataTable.AsEnumerable()
                  group b by b.Field<string>("chargetag") into g
                  select new
                  {
                      ChargeTag = g.Key,
                      Count = g.Count(),
                      ChargeSum = g.Sum(x => x.Field<int>("charge"))
                  };

(I've removed the let clause here as it wasn't really buying you anything.)

Now that may be inefficient; it may end up grouping twice in order to perform two aggregation operations. You could fix that like with a query continuation like this, if you really wanted:

var groupedData = from b in dataTable.AsEnumerable()
                  group b by b.Field<string>("chargetag") into g
                  select new
                  {
                      ChargeTag = g.Key,
                      List = g.ToList(),
                  } into g
                  select new 
                  {
                      g.ChargeTag,
                      Count = g.List.Count,
                      ChargeSum = g.List.Sum(x => x.Field<int>("charge"))
                  };

Or with a let clause instead:

var groupedData = from b in dataTable.AsEnumerable()
                  group b by b.Field<string>("chargetag") into g
                  let list = g.ToList()
                  select new
                  {
                      ChargeTag = g.Key,
                      Count = list.Count,
                      ChargeSum = list.Sum(x => x.Field<int>("charge"))
                  };
Jon Skeet
Wow, that was FAST!! :-) I'll try that in a minute...
jarod1701
Nice explanation (as usual). I'd be interested to know if the first option actually groups twice or if it gets optimised.
KJN
Works perfectly (of course ;-) ) Thanks again!
jarod1701