2016-05-16 37 views
3

我有一个表中sql server这样如何在LINQ的枢轴数据没有硬编码列

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() 
+0

“*但这只是一半的工作*“另一半是什么?转换为'DataTable'?这不是LINQ任务。 –

+0

@Ivan Stoev其实我的linq代码不会将数据转换为数据透视格式,我需要将其转换为透视格式,我修改了我的问题。 – 3355307

+0

尝试在http://techbrij.com/pivot-c-array-datatable-convert-column-to-row-linq中提供的解决方案1 ​​ – Sarathy

回答

2

我已通过修改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); 
+0

奇妙的解决方案,它为我工作。 CodeID和ItemID是外键,因为它们在其父表中有说明。是否可以显示描述而不是ID。在所有行的第1列以及所有列标题的描述中,而不是D1,D2,D3 .. – 3355307