【问题标题】:How to pivot data in LINQ without hard coding columns [duplicate]如何在没有硬编码列的情况下在 LINQ 中透视数据 [重复]
【发布时间】:2016-09-12 00:54:42
【问题描述】:

我在sql server 有一张这样的桌子

CodeItemsRule Table 
CodeID  ItemID RuleID 
00009   D1      2   
00009   D2      2
00009   D3      1
00008   D1      3
00007   D3      1
00007   D4      1
00010   D3      2
00010   D1      1
00010   D2      1

我需要像这样在LINQ 中旋转这些数据。

CodeID  D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 D14
00007          1  1
00009   2   2  1

下面给出的是我的代码,但它不会将其转换为数据透视格式。

List<CodeItemsRule> _CodeItemRules = new CodeItemsRuleRepository.GetAll();
var _GroupResult = _CodeItemRules.GroupBy(g => g.CodeID).Select(g => new 
{
    CodeID = g.Key,
    ItemRulesList = g.ToDictionary(t => t.ItemID, t => t.RuleID)
}).ToList()

【问题讨论】:

  • "但这完成了一半的工作" 另一半是什么?转换为DataTable?那不是 LINQ 任务。
  • @Ivan Stoev 实际上我的 linq 代码不会将数据转换为数据透视格式,我需要将其转换为数据透视格式我已经修改了我的问题。

标签: c# linq datatable pivot


【解决方案1】:

我通过修改the link 中的详细信息为您简化了解决方案。

首先在静态类中创建扩展方法ToPivotTable

public static class PivotClass
{
    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;
    }
}

然后,使用列表中的此扩展方法来获取您的枢轴DataTable,如下所述:

List<CodeItemsRule> _CodeItemRules = new List<CodeItemsRule>()
{
    new CodeItemsRule()
    {
        CodeID="00009",
        ItemID="D1",
        RuleID=2
    },new CodeItemsRule()
    {
        CodeID="00009",
        ItemID="D2",
        RuleID=2
    },new CodeItemsRule()
    {
        CodeID="00009",
        ItemID="D3",
        RuleID=1
    },new CodeItemsRule()
    {
        CodeID="00008",
        ItemID="D1",
        RuleID=3
    },new CodeItemsRule()
    {
        CodeID="00007",
        ItemID="D3",
        RuleID=1
    },new CodeItemsRule()
    {
        CodeID="00007",
        ItemID="D4",
        RuleID=1
    },new CodeItemsRule()
    {
        CodeID="00010",
        ItemID="D3",
        RuleID=2
    },new CodeItemsRule()
    {
        CodeID="00010",
        ItemID="D1",
        RuleID=1
    },new CodeItemsRule()
    {
        CodeID="00010",
        ItemID="D2",
        RuleID=1
    }

};
var pivotTable = _CodeItemRules.ToPivotTable(
    item => item.ItemID,
    item => item.CodeID,
    items => items.Any() ? items.Sum(x => x.RuleID) : 0);

【讨论】:

  • 它为我工作的绝佳解决方案。 CodeID 和 ItemID 是外键,因为它们在父表中有描述。是否可以显示描述而不是 ID。在所有行的第 1 列以及所有列标题的描述,而不是 D1、D2、D3..
  • 如何自定义ToPivotTable() 函数,因为它可以接受多个字段名称,将在哪个字段上执行分组......任何想法将不胜感激。谢谢
猜你喜欢
  • 2019-01-12
  • 1970-01-01
  • 2022-12-03
  • 1970-01-01
  • 2021-10-06
  • 1970-01-01
  • 2018-06-09
  • 1970-01-01
  • 2023-01-07
相关资源
最近更新 更多