我使用C#开发了一个Windows应用程序。使用DataTable列出所有信息。该数据表具有重复值。
我的结果:
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
预期结果:
Lead Owners <2Days <5Days <10Days <20Days >20Days Grand-Total
Dan Mahoney 1
Richard James Whitaker 7
Wayne Dunne 3
我需要一个linq查询来实现预期的结果。
请帮我解决这个问题。 提前谢谢。
答案 0 :(得分:2)
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
}
如果您真的需要DataTable,可以使用CopyToDataTable方法从查询结果中创建新的DataTable:Creating a DataTable From a Query
答案 1 :(得分:2)
如果要创建包含聚合值的新DataTable
,LINQ不是整个任务的最佳工具。您应该使用DataTable.Clone
创建具有相同模式的空表。
然后使用可以在源表的键列上使用Enumerable.GroupBy
。最后使用循环添加带有聚合值的DataRow
:
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);
}
}
我假设数字列的类型是int
。
结果表:
Dan Mahoney null null 1
Richard James Whitaker null 7 null
Wayne Dunne 3 null null