简体   繁体   中英

DataTable linq query to group by a column

I have developed a Windows application using C#. Used a DataTable to list all information. That Data-Table has duplicate values.

My result:

Lead Owners             <2Days  <5Days  <10Days <20Days >20Days Grand-Total
Dan Mahoney                                1                
Richard James Whitaker            1             
Richard James Whitaker            1             
Richard James Whitaker            1             
Richard James Whitaker            1             
Wayne Dunne              1              
Wayne Dunne              1              
Richard James Whitaker            1             
Wayne Dunne              1              
Richard James Whitaker            1             
Richard James Whitaker            1             

Expected Result:

Lead Owners             <2Days  <5Days  <10Days <20Days >20Days Grand-Total
Dan Mahoney                                1                
Richard James Whitaker            7             
Wayne Dunne              3              

I need a linq query to achieve the expected result.

Kindly help me to get this. Thanks in advance.

from r in table.AsEnumerable()
group r by r.Field<string>("Lead Owners") into g
select new {
   LeadOwners = g.Key,
   2Days = g.Sum(r => r.Field<int?>("2Days")),
   5Days = g.Sum(r => r.Field<int?>("5Days"))
   // etc
}

You can use CopyToDataTable method to create new DataTable from query results, if you really need it to be DataTable: Creating a DataTable From a Query

If you want to create a new DataTable that contains the aggregated values LINQ is not the best tool for the whole task. You should use DataTable.Clone to create an empty table with the same schema.

Then use can use Enumerable.GroupBy on your source table's key-column. Finally use a loop to add the DataRow s with the aggregated values:

var ownerGroups = dt.AsEnumerable()
    .GroupBy(row => row.Field<string>("Lead Owners"));
var dt2 = dt.Clone();
var intColumns = dt2.Columns.Cast<DataColumn>()
    .Where(c => c.DataType == typeof(int)).ToArray();
foreach (var grp in ownerGroups)
{
    var row = dt2.Rows.Add();
    row.SetField("Lead Owners", grp.Key);
    foreach (DataColumn col in intColumns)
    {
        bool anyNonNull = grp.Any(r => r.Field<int?>(col.Ordinal).HasValue);
        int? sum = anyNonNull ? grp.Sum(r => r.Field<int?>(col.Ordinal)) : null;
        row.SetField(col, sum);
    }
}

I have presumed that the type of the numeric columns is int .

Resulting table:

Dan Mahoney                 null        null       1
Richard James Whitaker      null        7          null 
Wayne Dunne                 3           null       null 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM