Linq group由多列组成,其中一列是可选的

时间:2018-05-22 10:59:18

标签: c# linq

我有一个由

组成的表格
MyDate(DATETIME),
Type nvarchar(255),
PropertyAId(int),
PropertyBId(int),
Data1 (float),
Data2 (float),
...
Data50 (float)

我想返回一个分组的表 MyDate,Type和PropertyAId,PropertyBId之一(取决于用户选择) 并且总结所有数据列。我更希望根据前缀或数据类型求和并选择数据列,而不必重复相同的行50次

到目前为止,我有点难看

 DataTable dt2 = dt.Clone();
            var grouped = dt.AsEnumerable().
                GroupBy(r => new
                {
                    MyDate = r.Field<DateTime>("MyDate"),
                    PropertyAId = selectedGroupingColumn == "PropertyAId" ? r.Field<int?>("PropertyAId") : null,
                    PropertyBId = selectedGroupingColumn == "PropertyBId" ? r.Field<int?>("PropertyBId") : null,
                    Type  = r.Field<string>("Type")
                });

            foreach (var group in grouped)
            {
                DataRow row = dt2.NewRow();

                foreach (var col in dt.Columns.Cast<DataColumn>())
                {
                    if (col.ColumnName.StartsWith("Data"))
                    {
                        double sum = 0;
                        if (col.DataType == typeof(double))
                            sum = group.Sum(r => r.Field<double>(col));

                        row.SetField(col.ColumnName, sum);
                    }
                    else
                        row[col.ColumnName] = group.First()[col];

                }
                dt2.Rows.Add(row);
            }

            //dt2.Columns.Remove unselected property and return table

1 个答案:

答案 0 :(得分:0)

您的逻辑似乎(大部分)听起来很合理,但我建议您直接使用selectedGroupingColumn来获取分组值,并仅设置double类型的“数据”列的总和: / p>

DataTable dt2 = dt.Clone();
var grouped = dt.AsEnumerable().
    GroupBy(r => new {
        MyDate = r.Field<DateTime>("MyDate"),
        GroupingColumnValue = r.Field<int?>(selectedGroupingColumn),
        Type = r.Field<string>("Type")
    });

foreach (var group in grouped) {
    DataRow row = dt2.NewRow();

    foreach (var col in dt.Columns.Cast<DataColumn>())
        if (col.ColumnName.StartsWith("Data") && col.DataType == typeof(double))
            row.SetField(col.ColumnName, group.Sum(r => r.Field<double>(col)));
        else
            row[col.ColumnName] = group.First()[col];

    dt2.Rows.Add(row);
}