把开源内的方法扒过来 加断点调吧
ToPivotList1 因其方法内参数有this IEnumerable<T> source ,这样在使用的时候是可以在原查询中ToPivotList1()后边点出来的.
参数 columnSelector 是对象 行转成的扩列 , rowSelector 保留列 dataSelector 对应sum 也就是数值列.
调用方法:查询.ToList().ToPivotTable(it => it.行转列的字段, it => it.保留列的字段, its => its.Any() ? its.Sum(x => x.数值字段):0);
最终找到是扩列前 扩列的字段有空值. 怼给datagridview后不显示最终建议使用 ToPivotTable()参数都一样, 转换成datatable.datagridview 能直接认出来的.
public static class DataHelper { public static List<dynamic> ToPivotList1<T, TColumn, TRow, TData>( this IEnumerable<T> source, Func<T, TColumn> columnSelector, Expression<Func<T, TRow>> rowSelector, Func<IEnumerable<T>, TData> dataSelector) { var arr = new List<object>(); var cols = new List<string>(); var rowName = ""; if (rowSelector.Body is MemberExpression) rowName = ((MemberExpression)rowSelector.Body).Member.Name; else rowName = "Group_" + string.Join("_", ((NewExpression)rowSelector.Body).Arguments.Select(it => it as MemberExpression).Select(it => it.Member.Name)); var columns = source.Select(columnSelector).Distinct(); cols = (new[] { rowName }).Concat(columns.Select(x => x?.ToString())).ToList(); 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)) }).ToList(); foreach (var row in rows) { var items = row.Values.Cast<object>().ToList(); items.Insert(0, row.Key); var obj = GetAnonymousObject(cols, items); arr.Add(obj); } return arr.ToList(); } private static dynamic GetAnonymousObject(IEnumerable<string> columns, IEnumerable<object> values) { IDictionary<string, object> eo = new ExpandoObject() as IDictionary<string, object>; int i; for (i = 0; i < columns.Count(); i++) { eo.Add(columns.ElementAt<string>(i), values.ElementAt<object>(i)); } return eo; } }
技术交流qq群:143280841