diff --git a/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableExecuteSql.cs b/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableExecuteSql.cs index 083d57d66..5e9f06b7a 100644 --- a/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableExecuteSql.cs +++ b/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableExecuteSql.cs @@ -224,13 +224,17 @@ namespace SqlSugar { return this.Context.Utilities.SerializeObject(this.ToPageList(pageIndex, pageSize, ref totalNumber), typeof(T)); } + + #region 内存行转列 + + #region 同步 public virtual DataTable ToPivotTable(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) { return this.ToList().ToPivotTable(columnSelector, rowSelector, dataSelector); } public virtual List ToPivotList(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) { - return ToPivotEnumerable(columnSelector,rowSelector,dataSelector).ToList(); + return ToPivotEnumerable(columnSelector, rowSelector, dataSelector).ToList(); } public virtual IEnumerable ToPivotEnumerable(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) { @@ -238,9 +242,33 @@ namespace SqlSugar } public virtual string ToPivotJson(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) { - var list = this.ToPivotList(columnSelector, rowSelector, dataSelector); + var list = ToPivotEnumerable(columnSelector, rowSelector, dataSelector).ToList(); return this.Context.Utilities.SerializeObject(list); } + #endregion + + #region 异步 + public virtual async Task ToPivotTableAsync(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) + { + return (await this.ToListAsync()).ToPivotTable(columnSelector, rowSelector, dataSelector); + } + public virtual async Task> ToPivotListAsync(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) + { + return (await ToPivotEnumerableAsync(columnSelector, rowSelector, dataSelector)).ToList(); + } + public virtual async Task> ToPivotEnumerableAsync(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) + { + return (await this.ToListAsync()).ToPivotList(columnSelector, rowSelector, dataSelector); + } + public virtual async Task ToPivotJsonAsync(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) + { + var list = (await ToPivotEnumerableAsync(columnSelector, rowSelector, dataSelector)).ToList(); + return this.Context.Utilities.SerializeObject(list); + } + #endregion + + #endregion + public List ToChildList(Expression> parentIdExpression, object primaryKeyValue, bool isContainOneself = true) { var entity = this.Context.EntityMaintenance.GetEntityInfo(); diff --git a/Src/Asp.Net/SqlSugar/Interface/IQueryable.cs b/Src/Asp.Net/SqlSugar/Interface/IQueryable.cs index 088fc1de5..31714f06e 100644 --- a/Src/Asp.Net/SqlSugar/Interface/IQueryable.cs +++ b/Src/Asp.Net/SqlSugar/Interface/IQueryable.cs @@ -285,10 +285,25 @@ namespace SqlSugar void AddQueue(); ISugarQueryable IgnoreColumns(Expression> columns); ISugarQueryable IgnoreColumns(params string[] columns); - DataTable ToPivotTable(Func columnSelector,Expression> rowSelector,Func, TData> dataSelector); + + #region 内存行转列 + + #region 同步 + DataTable ToPivotTable(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector); List ToPivotList(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector); IEnumerable ToPivotEnumerable(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector); string ToPivotJson(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector); + #endregion + + #region 异步 + Task ToPivotTableAsync(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector); + Task> ToPivotListAsync(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector); + Task> ToPivotEnumerableAsync(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector); + Task ToPivotJsonAsync(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector); + #endregion + + #endregion + ISugarQueryable SplitTable(Func,IEnumerable> getTableNamesFunc); ISugarQueryable SplitTable(DateTime beginTime,DateTime endTime); ISugarQueryable SplitTable(); diff --git a/Src/Asp.NetCore2/MySqlTest/a9_ToPivot.cs b/Src/Asp.NetCore2/MySqlTest/a9_ToPivot.cs index a976e128c..f01b14a67 100644 --- a/Src/Asp.NetCore2/MySqlTest/a9_ToPivot.cs +++ b/Src/Asp.NetCore2/MySqlTest/a9_ToPivot.cs @@ -22,6 +22,10 @@ namespace MySqlTest db.CodeFirst.SetStringDefaultLength(200).InitTables(typeof(RowToColumn)); Clean(); InitData(); + Test1(); + Test2(); + Test3(); + Test4(); Test5(); Test6(); } @@ -66,7 +70,86 @@ namespace MySqlTest var db = DbHelper.GetNewDb(); db.DbMaintenance.TruncateTable(); } + public static void Test1() + { + var db = DbHelper.GetNewDb(); + // 创建 Stopwatch 对象并开始计时 + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + var s = new DateTime(2023, 2, 1); + var e = new DateTime(2023, 6, 1).AddMilliseconds(-1); + var ls = db.Queryable() + .Where(x => x.Date >= s && x.Date <= e) + .GroupBy(x => new { x.Code, x.Date, x.Val, x.T1, x.T2 }) + .Select(x => new { x.Code, x.Date, x.T1, x.T2, Val = SqlFunc.AggregateSum(x.Val) })//求和可以自动处理空值 + .ToPivotTable(it => it.Code, it => it.T1, it => it.Any() ? it.Sum(x => x.Val) : 0); + // 结束计时并获取经过的时间 + stopwatch.Stop(); + TimeSpan elapsedTime = stopwatch.Elapsed; + + Console.WriteLine("T1:" + elapsedTime); + } + public static void Test2() + { + var db = DbHelper.GetNewDb(); + // 创建 Stopwatch 对象并开始计时 + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + var s = new DateTime(2023, 2, 1); + var e = new DateTime(2023, 6, 1).AddMilliseconds(-1); + var ls = db.Queryable() + .Where(x => x.Date >= s && x.Date <= e) + .GroupBy(x => new { x.Code, x.Date, x.Val, x.T1, x.T2 }) + .Select(x => new { x.Code, x.Date, x.T1, x.T2, Val = SqlFunc.AggregateSum(x.Val) })//求和可以自动处理空值 + .ToPivotList(it => it.Code, it => it.T1, it => it.Any() ? it.Sum(x => x.Val) : 0); + + // 结束计时并获取经过的时间 + stopwatch.Stop(); + TimeSpan elapsedTime = stopwatch.Elapsed; + + Console.WriteLine("T2:" + elapsedTime); + } + public static void Test3() + { + var db = DbHelper.GetNewDb(); + // 创建 Stopwatch 对象并开始计时 + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + var s = new DateTime(2023, 2, 1); + var e = new DateTime(2023, 6, 1).AddMilliseconds(-1); + var ls = db.Queryable() + .Where(x => x.Date >= s && x.Date <= e) + .GroupBy(x => new { x.Code, x.Date, x.Val, x.T1, x.T2 }) + .Select(x => new { x.Code, x.Date, x.T1, x.T2, Val = SqlFunc.AggregateSum(x.Val) })//求和可以自动处理空值 + .ToPivotTable(it => it.Code, it => it.Date, it => it.Any() ? it.Sum(x => x.Val) : 0); + + // 结束计时并获取经过的时间 + stopwatch.Stop(); + TimeSpan elapsedTime = stopwatch.Elapsed; + + Console.WriteLine("T3:" + elapsedTime); + } + public static void Test4() + { + var db = DbHelper.GetNewDb(); + // 创建 Stopwatch 对象并开始计时 + Stopwatch stopwatch = new Stopwatch(); + stopwatch.Start(); + var s = new DateTime(2023, 2, 1); + var e = new DateTime(2023, 6, 1).AddMilliseconds(-1); + var ls = db.Queryable() + .Where(x => x.Date >= s && x.Date <= e) + .GroupBy(x => new { x.Code, x.Date, x.Val, x.T1, x.T2 }) + .Select(x => new { x.Code, x.Date, x.T1, x.T2, Val = SqlFunc.AggregateSum(x.Val) })//求和可以自动处理空值 + .ToPivotList(it => it.Code, it => it.Date, it => it.Any() ? it.Sum(x => x.Val) : 0); + + // 结束计时并获取经过的时间 + stopwatch.Stop(); + TimeSpan elapsedTime = stopwatch.Elapsed; + + Console.WriteLine("T4:" + elapsedTime); + } public static void Test5() { var db = DbHelper.GetNewDb(); @@ -105,7 +188,7 @@ namespace MySqlTest stopwatch.Stop(); TimeSpan elapsedTime = stopwatch.Elapsed; - Console.WriteLine("T000:" + elapsedTime); + Console.WriteLine("T6:" + elapsedTime); } } diff --git a/Src/Asp.NetCore2/SqlSugar/Abstract/QueryableProvider/QueryableExecuteSql.cs b/Src/Asp.NetCore2/SqlSugar/Abstract/QueryableProvider/QueryableExecuteSql.cs index 083d57d66..5e9f06b7a 100644 --- a/Src/Asp.NetCore2/SqlSugar/Abstract/QueryableProvider/QueryableExecuteSql.cs +++ b/Src/Asp.NetCore2/SqlSugar/Abstract/QueryableProvider/QueryableExecuteSql.cs @@ -224,13 +224,17 @@ namespace SqlSugar { return this.Context.Utilities.SerializeObject(this.ToPageList(pageIndex, pageSize, ref totalNumber), typeof(T)); } + + #region 内存行转列 + + #region 同步 public virtual DataTable ToPivotTable(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) { return this.ToList().ToPivotTable(columnSelector, rowSelector, dataSelector); } public virtual List ToPivotList(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) { - return ToPivotEnumerable(columnSelector,rowSelector,dataSelector).ToList(); + return ToPivotEnumerable(columnSelector, rowSelector, dataSelector).ToList(); } public virtual IEnumerable ToPivotEnumerable(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) { @@ -238,9 +242,33 @@ namespace SqlSugar } public virtual string ToPivotJson(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) { - var list = this.ToPivotList(columnSelector, rowSelector, dataSelector); + var list = ToPivotEnumerable(columnSelector, rowSelector, dataSelector).ToList(); return this.Context.Utilities.SerializeObject(list); } + #endregion + + #region 异步 + public virtual async Task ToPivotTableAsync(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) + { + return (await this.ToListAsync()).ToPivotTable(columnSelector, rowSelector, dataSelector); + } + public virtual async Task> ToPivotListAsync(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) + { + return (await ToPivotEnumerableAsync(columnSelector, rowSelector, dataSelector)).ToList(); + } + public virtual async Task> ToPivotEnumerableAsync(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) + { + return (await this.ToListAsync()).ToPivotList(columnSelector, rowSelector, dataSelector); + } + public virtual async Task ToPivotJsonAsync(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) + { + var list = (await ToPivotEnumerableAsync(columnSelector, rowSelector, dataSelector)).ToList(); + return this.Context.Utilities.SerializeObject(list); + } + #endregion + + #endregion + public List ToChildList(Expression> parentIdExpression, object primaryKeyValue, bool isContainOneself = true) { var entity = this.Context.EntityMaintenance.GetEntityInfo(); diff --git a/Src/Asp.NetCore2/SqlSugar/Interface/IQueryable.cs b/Src/Asp.NetCore2/SqlSugar/Interface/IQueryable.cs index 088fc1de5..31714f06e 100644 --- a/Src/Asp.NetCore2/SqlSugar/Interface/IQueryable.cs +++ b/Src/Asp.NetCore2/SqlSugar/Interface/IQueryable.cs @@ -285,10 +285,25 @@ namespace SqlSugar void AddQueue(); ISugarQueryable IgnoreColumns(Expression> columns); ISugarQueryable IgnoreColumns(params string[] columns); - DataTable ToPivotTable(Func columnSelector,Expression> rowSelector,Func, TData> dataSelector); + + #region 内存行转列 + + #region 同步 + DataTable ToPivotTable(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector); List ToPivotList(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector); IEnumerable ToPivotEnumerable(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector); string ToPivotJson(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector); + #endregion + + #region 异步 + Task ToPivotTableAsync(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector); + Task> ToPivotListAsync(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector); + Task> ToPivotEnumerableAsync(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector); + Task ToPivotJsonAsync(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector); + #endregion + + #endregion + ISugarQueryable SplitTable(Func,IEnumerable> getTableNamesFunc); ISugarQueryable SplitTable(DateTime beginTime,DateTime endTime); ISugarQueryable SplitTable();