Search code examples
c#linqdatatable

Use LINQ to group data from DataTable


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?


Solution

  • 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"))
                      };