2016-05-16 61 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