行列旋转 Pivot

原文: https://stackoverflow.com/questions/37250446/how-to-pivot-data-in-linq-without-hard-coding-columns

例子如下:

 文中给出的解决方案

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;
    }
}

  

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

 

posted @ 2024-09-04 17:39  katesharing  阅读(5)  评论(0编辑  收藏  举报