Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用动态列数聚合datatable_C#_Dataset_Linq To Dataset - Fatal编程技术网

C# 使用动态列数聚合datatable

C# 使用动态列数聚合datatable,c#,dataset,linq-to-dataset,C#,Dataset,Linq To Dataset,我有一个带有动态列集的datatable,希望聚合基于数值的列,并将最后的行保留到新的datatable中 数据表示例:- PartnerName CreditCol DebitCol AmountCol .... P1 10 20 30 P2 1 2 3 P3 3 1 10 P2 1

我有一个带有动态列集的datatable,希望聚合基于数值的列,并将最后的行保留到新的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查询或任何其他解决方案。

以下是一种适合您需求的动态方法:

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];
    }
}
结果:

PartnerName   CreditCol    DebitCol    AmountCol
P1            10             20         30
P2            2              102        203
P3            3              1          10

以下是一种适合您需求的动态方法:

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];
    }
}
结果:

PartnerName   CreditCol    DebitCol    AmountCol
P1            10             20         30
P2            2              102        203
P3            3              1          10

要聚合的列的类型始终是
int
?您要分组的列始终是一列,还是多列的组合?您尝试过什么吗?主键将基于一列,即PartnerName。对于数字列,它可以是字符串。但是我们必须将其转换为int以进行聚合。您希望它检查每一列是否所有行中的所有值都可以解析为
int
?您不能提供要求和的列吗?如果列包含
“10.0”
,该怎么办?这显然不是
int
,但它可以被解析为
decimal
,可以转换为
int
,也可以求和为带小数点的十进制值。我尝试执行datarow迭代,但它变得复杂了。我是Linq新手,可能在Linq查询中很容易操作。它总是包含整数数据,不必担心小数。但列集可能会有所不同。如果这是一个昂贵的评估,我们可以跳过解析检查。您希望聚合的列类型始终是
int
?您要分组的列始终是一列,还是多列的组合?您尝试过什么吗?主键将基于一列,即PartnerName。对于数字列,它可以是字符串。但是我们必须将其转换为int以进行聚合。您希望它检查每一列是否所有行中的所有值都可以解析为
int
?您不能提供要求和的列吗?如果列包含
“10.0”
,该怎么办?这显然不是
int
,但它可以被解析为
decimal
,可以转换为
int
,也可以求和为带小数点的十进制值。我尝试执行datarow迭代,但它变得复杂了。我是Linq新手,可能在Linq查询中很容易操作。它总是包含整数数据,不必担心小数。但列集可能会有所不同。如果这是一个昂贵的评估,我们可以跳过解析检查..谢谢soln,让我试着让你保持联系.谢谢soln,让我试着让你保持联系。