行列旋转 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);
本文来自博客园,转载请注明原文链接:https://www.cnblogs.com/keeplearningandsharing/p/18397015