【问题标题】:How to change the data layout of a data table with LINQ如何使用 LINQ 更改数据表的数据布局
【发布时间】:2013-09-03 02:58:09
【问题描述】:

以上是我的一个数据表的屏幕截图。我正在尝试将此数据转换为以下格式,以便可以将其绑定到我的一个网格。我尝试过 LINQ,但没有成功。 请任何人帮助我如何做到这一点。不一定是 LINQ,但我认为使用 LINQ 会更容易

【问题讨论】:

  • 您能展示一下您是如何尝试转换数据的吗?
  • 首先我从“对象”中获取不同的列,如下所示 var distinctColumnNames = dataSet.Tables["reportColumns"].AsEnumerable() .Select(row => new { colObject = row.Field("Object"), }).Distinct();
  • 然后我正在运行以下 Linq 语句 foreach (var columnName in distinctColumnNames) { var dataRow = dataSet.Tables["reportColumns"].AsEnumerable() .Select(rowData => new { colAttribute = rowData .Field("Attribute"), colValue = rowData.Field("Value"), colStandard = rowData.Field("Standard") }); }
  • 我缺少的一点是如何在第二个语句中应用 where 子句(例如 where dataRow.Object == "columnName")。我知道我没有在这里选择 Object 列,但是在 dataRow 中选择该列之后,where 子句将如何应用?
  • 我已经更改了我的第二个 Linq Select 语句并添加了“对象”列 foreach (var columnName in distinctColumnNames) { var dataRow = dataSet.Tables["reportColumns"].AsEnumerable() .Select( rowData => new { colObject = rowData.Field("Object"), colAttribute = rowData.Field("Attribute"), colValue = rowData.Field("Value"), colStandard = rowData .Field("标准") }); }

标签: c# linq datatable datatable.select


【解决方案1】:

下面试试

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

【讨论】:

  • 非常感谢达米特。结果给我带来了灿烂的笑容。非常感谢您的时间和精力。
【解决方案2】:

你可以使用我的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);

这将创建具有不同 Attribute 值(即 DefaultColumn、Label、Type)作为列的数据透视表,行将是每个 Object 值的组,并且每个单元格将具有对象组和属性列的相应 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);

【讨论】:

  • 嗨 Lazyberezovsky,非常感谢您的回复。我没有尝试过你的示例代码,因为我已经在使用 LINQ 方式,所以决定遵循 Damith 方法,它对我有用。
  • @waseem 这一种 Linq 方式。而且它不需要每个对象组三个查询
猜你喜欢
  • 1970-01-01
  • 2023-01-24
  • 1970-01-01
  • 1970-01-01
  • 2019-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多