Как изменить макет данных таблицы данных с помощью LINQ

Выше приведен снимок экрана с одной из моих таблиц данных. Я пытаюсь преобразовать эти данные в следующий формат, чтобы я мог привязать их к одной из моих таблиц. Я пробовал LINQ, но безуспешно. Может ли кто-нибудь помочь мне, как я могу это сделать. Не обязательно быть LINQ, но я думаю, что это будет проще с LINQ

2 ответа

Решение

Попробуйте ниже

var result =  dataSet.Tables["reportColumns"].AsEnumerable().GroupBy(x => x.Field<string>("Object"))
    .Select(g => new
    {
        ColumnName = g.Key,
        DefaultColumn = g.FirstOrDefault(p => p.Field<string>("Attribute") == "DefaultColumn").Field<string>("Value"),
        Label = g.FirstOrDefault(p => p.Field<string>("Attribute") == "Label").Field<string>("Value"),
        Type = g.FirstOrDefault(p => p.Field<string>("Attribute") == "Type").Field<string>("Value"),
        Standard = g.FirstOrDefault().Field<int>("Standard")
    }).ToList();

Вы можете использовать мое расширение ToPivotTable:

public static DataTable ToPivotTable<T, TColumn, TRow, TData>(
      this IEnumerable<T> source,
      Func<T, TColumn> columnSelector,
      Expression<Func<T, TRow>> rowSelector,
      Func<IEnumerable<T>, TData> dataSelector)
{
    DataTable table = new DataTable();
    var rowName = ((MemberExpression)rowSelector.Body).Member.Name;
    table.Columns.Add(new DataColumn(rowName));
    var columns = source.Select(columnSelector).Distinct();

    foreach (var column in columns)
        table.Columns.Add(new DataColumn(column.ToString()));

    var rows = source.GroupBy(rowSelector.Compile())
                     .Select(rowGroup => new
                     {
                         Key = rowGroup.Key,
                         Values = columns.GroupJoin(
                             rowGroup,
                             c => c,
                             r => columnSelector(r),
                             (c, columnGroup) => dataSelector(columnGroup))
                     });

    foreach (var row in rows)
    {
        var dataRow = table.NewRow();
        var items = row.Values.Cast<object>().ToList();
        items.Insert(0, row.Key);
        dataRow.ItemArray = items.ToArray();
        table.Rows.Add(dataRow);
    }

    return table;
}

Создайте строго типизированные данные из исходной таблицы:

var data = from r in table.AsEnumerable()
           select new {
                Object = r.Field<string>("Object"),
                Attribute = r.Field<string>("Attribute"),
                Value = r.Field<object>("Value")
           };

И преобразовать их в сводную таблицу:

var pivotTable = data.ToPivotTable(r => r.Attribute, 
                                   r => r.Object, 
                                   rows => rows.First().Value);

Это создаст сводную таблицу с различными значениями атрибута (т. Е. DefaultColumn, Label, Type) в виде столбцов, строки будут группами для каждого значения объекта, а каждая ячейка будет иметь значение соответствующего свойства Value для группы объектов и столбца атрибута.


Или в одном запросе:

var pivotTable = table.AsEnumerable()
                      .Select(r => new {
                          Object = r.Field<string>("Object"),
                          Attribute = r.Field<string>("Attribute"),
                          Value = r.Field<object>("Value")
                      })
                      .ToPivotTable(r => r.Attribute, 
                                    r => r.Object, 
                                    rows => rows.First().Value);
Другие вопросы по тегам