Группа Linq несколькими столбцами, одна из которых выбирается

j doe спросил: 28 апреля 2018 в 09:19 в: c#

У меня есть таблица, состоящая из

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 ответ

NetMage ответил: 29 апреля 2018 в 04:35

Ваша логика кажется (в основном) звуком, но я бы предложил просто использовать selectedGroupingColumn напрямую, чтобы получить значение для группировки, и только установить сумму для столбцов "Данные" типа double:

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);
}