diff --git a/Src/Asp.NetCore2/SqlSugar/Abstract/QueryableProvider/NavSelectHelper.cs b/Src/Asp.NetCore2/SqlSugar/Abstract/QueryableProvider/NavSelectHelper.cs new file mode 100644 index 000000000..30283c2d4 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar/Abstract/QueryableProvider/NavSelectHelper.cs @@ -0,0 +1,161 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace SqlSugar +{ + internal class NavSelectHelper + { + internal static List GetList(Expression> expression, QueryableProvider queryableProvider) + { + List result = new List (); + var isSqlFunc = IsSqlFunc(expression, queryableProvider); + if (isSqlFunc&&isGroup(expression, queryableProvider)) + { + var sqlfuncQueryable = queryableProvider.Clone(); + sqlfuncQueryable.QueryBuilder.Includes = null; + result = sqlfuncQueryable + .Select(expression) + .ToList(); + var includeQueryable = queryableProvider.Clone(); + includeQueryable.Select(GetGroupSelect(typeof(T), queryableProvider.Context)); + includeQueryable.QueryBuilder.NoCheckInclude=true; + MegerList(result, includeQueryable.ToList(), sqlfuncQueryable.Context); + } + else if (isSqlFunc) + { + var sqlfuncQueryable = queryableProvider.Clone(); + sqlfuncQueryable.QueryBuilder.Includes = null; + result = sqlfuncQueryable + .Select(expression) + .ToList(); + var includeList = queryableProvider.Clone().ToList(); + MegerList(result, includeList, sqlfuncQueryable.Context); + } + else + { + result= queryableProvider.ToList().Select(expression.Compile()).ToList(); + } + return result; + } + internal static async Task> GetListAsync(Expression> expression, QueryableProvider queryableProvider) + { + List result = new List(); + var isSqlFunc = IsSqlFunc(expression, queryableProvider); + if (isSqlFunc && isGroup(expression, queryableProvider)) + { + var sqlfuncQueryable = queryableProvider.Clone(); + sqlfuncQueryable.QueryBuilder.Includes = null; + result =await sqlfuncQueryable + .Select(expression) + .ToListAsync(); + var includeQueryable = queryableProvider.Clone(); + includeQueryable.Select(GetGroupSelect(typeof(T), queryableProvider.Context)); + includeQueryable.QueryBuilder.NoCheckInclude = true; + MegerList(result,await includeQueryable.ToListAsync(), sqlfuncQueryable.Context); + } + else if (isSqlFunc) + { + var sqlfuncQueryable = queryableProvider.Clone(); + sqlfuncQueryable.QueryBuilder.Includes = null; + result =await sqlfuncQueryable + .Select(expression) + .ToListAsync(); + var includeList =await queryableProvider.Clone().ToListAsync(); + MegerList(result, includeList, sqlfuncQueryable.Context); + } + else + { + var list =await queryableProvider.ToListAsync(); + result = list.Select(expression.Compile()).ToList(); + } + return result; + } + + private static string GetGroupSelect(Type type,SqlSugarProvider context) + { + var entity = context.EntityMaintenance.GetEntityInfo(type); + List selector = new List(); + foreach (var item in entity.Columns.Where(it=>it.IsIgnore==false)) + { + selector.Add($" min({item.DbColumnName}) as {item.DbColumnName}"); + } + return string.Join(",", selector); + } + + private static void MegerList(List result, List includeList,SqlSugarProvider context) + { + if (result.Count != includeList.Count) return; + var columns = context.EntityMaintenance.GetEntityInfo().Columns; + var resColumns = context.EntityMaintenance.GetEntityInfo().Columns; + var i = 0; + foreach (var item in includeList) + { + foreach (var column in columns) + { + if (column.Navigat != null) + { + var value = column.PropertyInfo.GetValue(item); + var resColumn=resColumns + .FirstOrDefault(z=> + z.PropertyName.Equals(column.PropertyName)&& + z.PropertyInfo.PropertyType==column.PropertyInfo.PropertyType + ); + if (resColumn != null) + { + var resItem= result[i]; + resColumn.PropertyInfo.SetValue(resItem,value); + } + } + } + i++; + } + } + + private static bool IsSqlFunc(Expression> expression, QueryableProvider queryableProvider) + { + var body=ExpressionTool.GetLambdaExpressionBody(expression); + if (body is NewExpression) + { + var newExp=((NewExpression)body); + foreach (var item in newExp.Arguments) + { + if (item is MethodCallExpression) + { + var method = ((MethodCallExpression)item).Method; + if (method.DeclaringType != null&& method.DeclaringType.Name=="SqlFunc") + { + return true; + } + } + } + } + if (body is MemberInitExpression) + { + var newExp = ((MemberInitExpression)body); + foreach (var item in newExp.Bindings) + { + MemberAssignment memberAssignment = (MemberAssignment)item; + if (memberAssignment.Expression is MethodCallExpression) + { + var method = ((MethodCallExpression)memberAssignment.Expression).Method; + if (method.DeclaringType != null && method.DeclaringType.Name == "SqlFunc") + { + return true; + } + } + } + } + return false; + } + + private static bool isGroup(Expression> expression, QueryableProvider queryableProvider) + { + var isGroup=queryableProvider.QueryBuilder.GetGroupByString.HasValue(); + return isGroup; + } + } +} diff --git a/Src/Asp.NetCore2/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs b/Src/Asp.NetCore2/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs index 853944f2e..b476ae77e 100644 --- a/Src/Asp.NetCore2/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs +++ b/Src/Asp.NetCore2/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs @@ -981,8 +981,9 @@ namespace SqlSugar { if (this.QueryBuilder.Includes != null && this.QueryBuilder.Includes.Count > 0) { - var list = this.ToList().Select(expression.Compile()).ToList(); - return list; + return NavSelectHelper.GetList(expression,this); + // var list = this.ToList().Select(expression.Compile()).ToList(); + // return list; } else { @@ -994,9 +995,7 @@ namespace SqlSugar { if (this.QueryBuilder.Includes != null && this.QueryBuilder.Includes.Count > 0) { - var result = await this.ToListAsync(); - var list = result.Select(expression.Compile()).ToList(); - return list; + return await NavSelectHelper.GetListAsync(expression, this); } else { @@ -2781,7 +2780,7 @@ namespace SqlSugar if (this.QueryBuilder.Includes != null) { var managers=(this.QueryBuilder.Includes as List); - if (this.QueryBuilder.SelectValue.HasValue()) + if (this.QueryBuilder.SelectValue.HasValue()&& this.QueryBuilder.NoCheckInclude==false) { Check.ExceptionEasy("To use includes, use select after tolist()", "使用Includes请在ToList()之后在使用Select"); } diff --git a/Src/Asp.NetCore2/SqlSugar/Abstract/SqlBuilderProvider/QueryBuilder.cs b/Src/Asp.NetCore2/SqlSugar/Abstract/SqlBuilderProvider/QueryBuilder.cs index 546479c7d..d34bb1aa1 100644 --- a/Src/Asp.NetCore2/SqlSugar/Abstract/SqlBuilderProvider/QueryBuilder.cs +++ b/Src/Asp.NetCore2/SqlSugar/Abstract/SqlBuilderProvider/QueryBuilder.cs @@ -762,6 +762,7 @@ namespace SqlSugar #region NoCopy internal bool IsClone { get; set; } + public bool NoCheckInclude { get; set; } #endregion private string GetTableName(string entityName) diff --git a/Src/Asp.NetCore2/SqlSugar/Abstract/SugarProvider/SqlSugarProvider.cs b/Src/Asp.NetCore2/SqlSugar/Abstract/SugarProvider/SqlSugarProvider.cs index bcec7d82e..c68bc750c 100644 --- a/Src/Asp.NetCore2/SqlSugar/Abstract/SugarProvider/SqlSugarProvider.cs +++ b/Src/Asp.NetCore2/SqlSugar/Abstract/SugarProvider/SqlSugarProvider.cs @@ -674,6 +674,7 @@ namespace SqlSugar #region Insertable public virtual IInsertable Insertable(T[] insertObjs) where T : class, new() { + UtilMethods.CheckArray(insertObjs); InitMappingInfo(); InsertableProvider result = this.CreateInsertable(insertObjs); return result; diff --git a/Src/Asp.NetCore2/SqlSugar/Utilities/UtilMethods.cs b/Src/Asp.NetCore2/SqlSugar/Utilities/UtilMethods.cs index 196885c6b..8ff8b35f1 100644 --- a/Src/Asp.NetCore2/SqlSugar/Utilities/UtilMethods.cs +++ b/Src/Asp.NetCore2/SqlSugar/Utilities/UtilMethods.cs @@ -819,5 +819,18 @@ namespace SqlSugar return result; } + + public static void CheckArray(T[] insertObjs) where T : class, new() + { + + if (insertObjs != null + && insertObjs.Length == 1 + && insertObjs.FirstOrDefault()!=null + && insertObjs.FirstOrDefault().GetType().FullName.Contains("System.Collections.Generic.List`")) + { + Check.ExceptionEasy("Insertable(T []) is an array and your argument is a List", "二次封装引起的进错重载,当前方法是 Insertable(T []) 参数是一个数组,而你的参数是一个List"); + } + } + } }