From 932dd36ab67a925b39e89f273deaef514e96dd7e Mon Sep 17 00:00:00 2001 From: sunkaixuan <610262374@qq.com> Date: Sat, 6 Jan 2024 23:19:02 +0800 Subject: [PATCH] Update ToPivotTable --- Src/Asp.Net/SqlSugar/SqlSugar.csproj | 1 + .../SqlSugar/Utilities/DataTableExtensions.cs | 9 ++ Src/Asp.Net/SqlSugar/Utilities/PivotHelper.cs | 129 ++++++++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 Src/Asp.Net/SqlSugar/Utilities/PivotHelper.cs diff --git a/Src/Asp.Net/SqlSugar/SqlSugar.csproj b/Src/Asp.Net/SqlSugar/SqlSugar.csproj index e9b4a5343..c2e8140ed 100644 --- a/Src/Asp.Net/SqlSugar/SqlSugar.csproj +++ b/Src/Asp.Net/SqlSugar/SqlSugar.csproj @@ -460,6 +460,7 @@ + diff --git a/Src/Asp.Net/SqlSugar/Utilities/DataTableExtensions.cs b/Src/Asp.Net/SqlSugar/Utilities/DataTableExtensions.cs index bedf25e72..825e2764c 100644 --- a/Src/Asp.Net/SqlSugar/Utilities/DataTableExtensions.cs +++ b/Src/Asp.Net/SqlSugar/Utilities/DataTableExtensions.cs @@ -18,6 +18,11 @@ namespace SqlSugar Expression> rowSelector, Func, TData> dataSelector) { + + if (rowSelector.Body is MemberExpression) + return PivotHelper.ToPivotTable(source, columnSelector, rowSelector, dataSelector); + + DataTable table = new DataTable(); var rowName = new List(); @@ -64,6 +69,10 @@ namespace SqlSugar Func, TData> dataSelector) { + if (rowSelector.Body is MemberExpression) + return PivotHelper.ToPivotList(source, columnSelector, rowSelector, dataSelector); + + var rowName = new List(); if (rowSelector.Body is MemberExpression) rowName.Add(((MemberExpression)rowSelector.Body).Member.Name); diff --git a/Src/Asp.Net/SqlSugar/Utilities/PivotHelper.cs b/Src/Asp.Net/SqlSugar/Utilities/PivotHelper.cs new file mode 100644 index 000000000..98920498e --- /dev/null +++ b/Src/Asp.Net/SqlSugar/Utilities/PivotHelper.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Dynamic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace SqlSugar +{ + internal static class PivotHelper + { + public static DataTable ToPivotTable( + IEnumerable source, + Func columnSelector, + Expression> rowSelector, + Func, TData> dataSelector) + { + DataTable table = new DataTable(); + var rowName = ""; + if (rowSelector.Body is MemberExpression) + rowName = ((MemberExpression)rowSelector.Body).Member.Name; + else + rowName = string.Join(UtilConstants.ReplaceKey, ((NewExpression)rowSelector.Body).Arguments.Select(it => it as MemberExpression).Select(it => it.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().ToList(); + items.Insert(0, row.Key); + dataRow.ItemArray = items.ToArray(); + table.Rows.Add(dataRow); + } + var firstName = table.Columns[0]?.ColumnName; + if (firstName.ObjToString().Contains(UtilConstants.ReplaceKey)) + { + int i = 0; + foreach (var item in Regex.Split(firstName, UtilConstants.ReplaceKey)) + { + i++; + table.Columns.Add(item); + table.Columns[item].SetOrdinal(i); + } + foreach (DataRow row in table.Rows) + { + var json = row[firstName]; + var list = json.ToString().TrimStart('{', ' ').TrimEnd('}', ' ') + .Split(new[] { ", " }, StringSplitOptions.None) + .Select(it => it.Split(new[] { " = " }, StringSplitOptions.None)).ToList(); + foreach (var item in Regex.Split(firstName, UtilConstants.ReplaceKey)) + { + var x = list.First(it => it.First().Trim() == item.Trim()); + row[item] = x[1]; + } + } + table.Columns.Remove(firstName); + } + return table; + } + public static List ToPivotList( + IEnumerable source, + Func columnSelector, + Expression> rowSelector, + Func, TData> dataSelector) + { + + var arr = new List(); + var cols = new List(); + 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().ToList(); + items.Insert(0, row.Key); + var obj = GetAnonymousObject(cols, items); + arr.Add(obj); + } + return arr.ToList(); + } + private static dynamic GetAnonymousObject(IEnumerable columns, IEnumerable values) + { + IDictionary eo = new ExpandoObject() as IDictionary; + int i; + for (i = 0; i < columns.Count(); i++) + { + eo.Add(columns.ElementAt(i), values.ElementAt(i)); + } + return eo; + } + } +}