mirror of
https://gitee.com/dotnetchina/SqlSugar.git
synced 2025-05-18 22:19:33 +08:00
Update ToPivotTable
This commit is contained in:
parent
6ee18ff5f1
commit
932dd36ab6
@ -460,6 +460,7 @@
|
|||||||
<Compile Include="Utilities\CallContext.cs" />
|
<Compile Include="Utilities\CallContext.cs" />
|
||||||
<Compile Include="Utilities\CallContextAsync.cs" />
|
<Compile Include="Utilities\CallContextAsync.cs" />
|
||||||
<Compile Include="Abstract\DynamicBuilder\DynamicBuilderHelper.cs" />
|
<Compile Include="Abstract\DynamicBuilder\DynamicBuilderHelper.cs" />
|
||||||
|
<Compile Include="Utilities\PivotHelper.cs" />
|
||||||
<Compile Include="Utilities\FastCopy.cs" />
|
<Compile Include="Utilities\FastCopy.cs" />
|
||||||
<Compile Include="Utilities\ExpressionBuilderHelper.cs" />
|
<Compile Include="Utilities\ExpressionBuilderHelper.cs" />
|
||||||
<Compile Include="Utilities\CommonExtensions.cs" />
|
<Compile Include="Utilities\CommonExtensions.cs" />
|
||||||
|
@ -18,6 +18,11 @@ namespace SqlSugar
|
|||||||
Expression<Func<T, TRow>> rowSelector,
|
Expression<Func<T, TRow>> rowSelector,
|
||||||
Func<IEnumerable<T>, TData> dataSelector)
|
Func<IEnumerable<T>, TData> dataSelector)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (rowSelector.Body is MemberExpression)
|
||||||
|
return PivotHelper.ToPivotTable(source, columnSelector, rowSelector, dataSelector);
|
||||||
|
|
||||||
|
|
||||||
DataTable table = new DataTable();
|
DataTable table = new DataTable();
|
||||||
|
|
||||||
var rowName = new List<string>();
|
var rowName = new List<string>();
|
||||||
@ -64,6 +69,10 @@ namespace SqlSugar
|
|||||||
Func<IEnumerable<T>, TData> dataSelector)
|
Func<IEnumerable<T>, TData> dataSelector)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (rowSelector.Body is MemberExpression)
|
||||||
|
return PivotHelper.ToPivotList(source, columnSelector, rowSelector, dataSelector);
|
||||||
|
|
||||||
|
|
||||||
var rowName = new List<string>();
|
var rowName = new List<string>();
|
||||||
if (rowSelector.Body is MemberExpression)
|
if (rowSelector.Body is MemberExpression)
|
||||||
rowName.Add(((MemberExpression)rowSelector.Body).Member.Name);
|
rowName.Add(((MemberExpression)rowSelector.Body).Member.Name);
|
||||||
|
129
Src/Asp.Net/SqlSugar/Utilities/PivotHelper.cs
Normal file
129
Src/Asp.Net/SqlSugar/Utilities/PivotHelper.cs
Normal file
@ -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<T, TColumn, TRow, TData>(
|
||||||
|
IEnumerable<T> source,
|
||||||
|
Func<T, TColumn> columnSelector,
|
||||||
|
Expression<Func<T, TRow>> rowSelector,
|
||||||
|
Func<IEnumerable<T>, 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<object>().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<dynamic> ToPivotList<T, TColumn, TRow, TData>(
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user