From b0d995a6b304e785deed4d6358a56ebfae34dd22 Mon Sep 17 00:00:00 2001 From: sunkaixuan <610262374@qq.com> Date: Mon, 10 Mar 2025 12:07:33 +0800 Subject: [PATCH] Optimize the group by --- .../QueryableProvider/QueryableHelper.cs | 19 ++++++++++++++++++- .../QueryableProvider/QueryableProvider.cs | 2 +- .../SqlBuilderProvider/QueryBuilder.cs | 17 ++++++++++++++--- .../SqlBuilder/SqlServerQueryBuilder.cs | 4 ++++ 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableHelper.cs b/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableHelper.cs index 7a169d9fc..5b4f99cf4 100644 --- a/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableHelper.cs +++ b/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableHelper.cs @@ -1731,6 +1731,8 @@ namespace SqlSugar } protected ISugarQueryable _GroupBy(Expression expression) { + var oldParameterNames = this.QueryBuilder.Parameters?.Select(it => it.ParameterName) + ?.ToList(); QueryBuilder.CheckExpression(expression, "GroupBy"); LambdaExpression lambda = expression as LambdaExpression; expression = lambda.Body; @@ -1761,7 +1763,19 @@ namespace SqlSugar lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); result = lamResult.GetResultString(); } - GroupBy(result); + if (oldParameterNames != null && this.Context.CurrentConnectionConfig.DbType == DbType.SqlServer) + { + var newParas = this.QueryBuilder.Parameters.Where(it => !oldParameterNames.Contains(it.ParameterName)).ToList(); + this.QueryBuilder.GroupParameters = newParas; + var groupBySql = UtilMethods.GetSqlString(DbType.SqlServer, result, newParas.ToArray()); + this.QueryBuilder.GroupBySql = groupBySql; + this.QueryBuilder.GroupBySqlOld = result; + GroupBy(result); + } + else + { + GroupBy(result); + } return this; } protected ISugarQueryable _As(string tableName, string entityName) @@ -2142,6 +2156,9 @@ namespace SqlSugar asyncQueryableBuilder.Hints = this.QueryBuilder.Hints; asyncQueryableBuilder.MasterDbTableName = this.QueryBuilder.MasterDbTableName; asyncQueryableBuilder.IsParameterizedConstructor = this.QueryBuilder.IsParameterizedConstructor; + asyncQueryableBuilder.GroupParameters = this.QueryBuilder.GroupParameters; + asyncQueryableBuilder.GroupBySql = this.QueryBuilder.GroupBySql; + asyncQueryableBuilder.GroupBySqlOld = this.QueryBuilder.GroupBySqlOld; if (this.QueryBuilder.AppendNavInfo != null) { asyncQueryableBuilder.AppendNavInfo = new AppendNavInfo() diff --git a/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs b/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs index 2d2c3abd3..a25d2bfe4 100644 --- a/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs +++ b/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs @@ -1341,7 +1341,7 @@ namespace SqlSugar return this; } public virtual ISugarQueryable GroupBy(Expression> expression) - { + { _GroupBy(expression); return this; } diff --git a/Src/Asp.Net/SqlSugar/Abstract/SqlBuilderProvider/QueryBuilder.cs b/Src/Asp.Net/SqlSugar/Abstract/SqlBuilderProvider/QueryBuilder.cs index 38e033ae0..a59bb27a4 100644 --- a/Src/Asp.Net/SqlSugar/Abstract/SqlBuilderProvider/QueryBuilder.cs +++ b/Src/Asp.Net/SqlSugar/Abstract/SqlBuilderProvider/QueryBuilder.cs @@ -34,6 +34,9 @@ namespace SqlSugar #endregion #region Splicing basic + public List GroupParameters { get; set; } + public string GroupBySql { get; set; } + public string GroupBySqlOld { get; set; } public Type AsType { get; set; } public bool IsParameterizedConstructor { get; set; } public string Hints { get; set; } @@ -283,7 +286,7 @@ namespace SqlSugar }; resolveExpress.Resolve(expression, resolveType); this.Parameters.AddRange(resolveExpress.Parameters.Select(it => new SugarParameter(it.ParameterName, it.Value, it.DbType) { Size=it.Size,TypeName=it.TypeName, IsNvarchar2=it.IsNvarchar2})); - var result = resolveExpress.Result; + var result = resolveExpress.Result; var isSingleTableHasSubquery = IsSingle() && resolveExpress.SingleTableNameSubqueryShortName.HasValue(); if (isSingleTableHasSubquery) { @@ -919,7 +922,15 @@ namespace SqlSugar { result = result + " AS columnName"; } - this.SelectCacheKey = result; + if (this.GroupParameters?.Any()==true && this.GroupBySql.HasValue()) + { + var selectSql = UtilMethods.GetSqlString(DbType.SqlServer, result, UtilMethods.CopySugarParameters(this.Parameters).ToArray()); + if (selectSql.Contains(this.GroupBySql)) + { + result = selectSql; + } + } + this.SelectCacheKey = result; return result; } } @@ -1090,7 +1101,7 @@ namespace SqlSugar public bool NoCheckInclude { get; set; } public virtual bool IsSelectNoAll { get; set; } = false; public List AutoAppendedColumns { get; set; } - public Dictionary MappingKeys { get; set; } + public Dictionary MappingKeys { get; set; } #endregion private string GetTableName(string entityName) diff --git a/Src/Asp.Net/SqlSugar/Realization/SqlServer/SqlBuilder/SqlServerQueryBuilder.cs b/Src/Asp.Net/SqlSugar/Realization/SqlServer/SqlBuilder/SqlServerQueryBuilder.cs index a0417bafb..393dde636 100644 --- a/Src/Asp.Net/SqlSugar/Realization/SqlServer/SqlBuilder/SqlServerQueryBuilder.cs +++ b/Src/Asp.Net/SqlSugar/Realization/SqlServer/SqlBuilder/SqlServerQueryBuilder.cs @@ -69,6 +69,10 @@ namespace SqlSugar if (isFirst && oldOrderByValue == "ORDER BY GETDATE() ") { this.OrderByValue = null; } var rowNumberString = string.Format(",ROW_NUMBER() OVER({0}) AS RowIndex ", GetOrderByString); string groupByValue = GetGroupByString + HavingInfos; + if (this.GroupParameters?.Any()==true) + { + groupByValue = groupByValue.Replace(this.GroupBySqlOld,this.GroupBySql); + } string orderByValue = (!isRowNumber && this.OrderByValue.HasValue()) ? GetOrderByString : null; if (isIgnoreOrderBy) { orderByValue = null; } sql.AppendFormat(SqlTemplate, GetSelect(isFirst,isTop), base.GetTableNameString, base.GetWhereValueString, groupByValue, orderByValue);