我有一个包含动态列列的数据表,并希望聚合基于数字的列并将最终行保存到新数据表中。
DataTable示例: -
PartnerName CreditCol DebitCol AmountCol ....
P1 10 20 30
P2 1 2 3
P3 3 1 10
P2 1 100 200
所需的输出应为: -
PartnerName CreditCol DebitCol AmountCol ....
P1 10 20 30
P2 2 102 203
P3 3 1 10
这里的主要内容是列集,将是动态的。有时,可能有两列,有时可能是20列。请建议linq查询或任何其他解决方案。
答案 0 :(得分:5)
这是一种适合您需求的动态方法:
var rows = table.AsEnumerable();
var columns = table.Columns.Cast<DataColumn>();
int i; // used to check if a string column can be parsed to int
string columnToGroup = "partnername";
DataColumn colToGroup = columns.First(c => c.ColumnName.Equals(columnToGroup, StringComparison.OrdinalIgnoreCase));
var colsToSum = columns
.Where(c => c != colToGroup &&
(c.DataType == typeof(int) ||
(c.DataType == typeof(string)
&& rows.All(r => int.TryParse(r.Field<string>(c), out i)))));
var columnsToSum = new HashSet<DataColumn>(colsToSum);
DataTable tblSum = table.Clone(); // empty table, same schema
foreach (var group in rows.GroupBy(r => r[colToGroup]))
{
DataRow row = tblSum.Rows.Add();
foreach(var col in columns)
{
if (columnsToSum.Contains(col))
{
int sum;
if (col.DataType == typeof(int))
sum = group.Sum(r => r.Field<int>(col));
else
sum = group.Sum(r => int.Parse(r.Field<string>(col)));
row.SetField(col.ColumnName, sum);
}
else
row[col.ColumnName] = group.First()[col];
}
}
在此处测试您的示例数据:
var table = new System.Data.DataTable();
table.Columns.Add("PartnerName", typeof(string));
table.Columns.Add("CreditCol", typeof(int));
table.Columns.Add("DebitCol", typeof(string));
table.Columns.Add("AmountCol", typeof(int));
table.Rows.Add("P1", 10, "20", 30);
table.Rows.Add("P2", 1, "2", 3);
table.Rows.Add("P3", 3, "1", 10);
table.Rows.Add("P2", 1, "100", 200);
结果:
PartnerName CreditCol DebitCol AmountCol
P1 10 20 30
P2 2 102 203
P3 3 1 10