diff --git a/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableHelper.cs b/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableHelper.cs index d29c80e61..7a2d9e476 100644 --- a/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableHelper.cs +++ b/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableHelper.cs @@ -1693,7 +1693,13 @@ namespace SqlSugar { var ps = this.QueryBuilder.Parameters; var itemProperty = typeof(TResult).GetProperty(subPara.Key); - var callType = itemProperty.PropertyType.GetGenericArguments()[0]; + var callType = itemProperty.PropertyType.GetGenericArguments().FirstOrDefault(); + var isFirst = false; + if (callType == null) + { + callType = itemProperty.PropertyType; + isFirst = true; + } var sql = subPara.Value.ObjToString().Replace("@sugarIndex", "0"); sql =SqlBuilder.RemoveParentheses(sql); var methodParamters = new object[] { sql, ps }; @@ -1711,7 +1717,14 @@ namespace SqlSugar } else { - itemProperty.SetValue(item, subList); + if (isFirst) + { + itemProperty.SetValue(item, (subList as IList)[0] ); + } + else + { + itemProperty.SetValue(item, subList); + } } } } @@ -1741,10 +1754,14 @@ namespace SqlSugar index++; } - var itemProperty = typeof(TResult).GetProperty(subPara.Key); - var callType = itemProperty.PropertyType.GetGenericArguments()[0]; - + var callType = itemProperty.PropertyType.GetGenericArguments().FirstOrDefault(); + var isFirst = false; + if (callType == null) + { + callType = itemProperty.PropertyType; + isFirst = true; + } var sqlstring = string.Join(" \r\n UNION ALL ", sqls); var methodParamters = new object[] { sqlstring, ps.ToArray() }; this.QueryBuilder.SubToListParameters = null; @@ -1755,7 +1772,11 @@ namespace SqlSugar var subList = ExpressionBuilderHelper.CallFunc(callType, methodParamters, this.Clone(), "SubQueryList"); var appendValue = this.QueryBuilder.AppendValues; var list = (subList as IEnumerable).Cast().ToList(); - if (typeof(TResult).IsAnonymousType()) + if (isFirst) + { + SetSubListWithClassFirst(result, itemProperty, appendValue, list, 0); + } + else if (typeof(TResult).IsAnonymousType()) { SetSubListWithAnonymousType(result, itemProperty, appendValue, list, 0); } @@ -1791,6 +1812,30 @@ namespace SqlSugar } return resIndex; } + private static int SetSubListWithClassFirst(List result, PropertyInfo itemProperty, List> appendValue, List list, int resIndex) + { + foreach (var item in result) + { + //var setValue = Activator.CreateInstance(itemProperty.PropertyType, true); + if (appendValue != null) + { + var appindex = 0; + foreach (var appValue in appendValue) + { + if (appValue[0].Value.ObjToInt() == resIndex) + { + var addItem = list[appindex]; + itemProperty.SetValue(item, addItem); + } + appindex++; + } + } + //itemProperty.SetValue(item, setValue); + resIndex++; + } + + return resIndex; + } private static int SetSubListWithClass(List result, PropertyInfo itemProperty, List> appendValue, List list, int resIndex) { diff --git a/Src/Asp.Net/SqlSugar/ExpressionsToSql/ResolveItems/BaseResolve_Validate.cs b/Src/Asp.Net/SqlSugar/ExpressionsToSql/ResolveItems/BaseResolve_Validate.cs index f603362b8..fe2524dae 100644 --- a/Src/Asp.Net/SqlSugar/ExpressionsToSql/ResolveItems/BaseResolve_Validate.cs +++ b/Src/Asp.Net/SqlSugar/ExpressionsToSql/ResolveItems/BaseResolve_Validate.cs @@ -14,7 +14,7 @@ namespace SqlSugar private static bool IsSubToList(Expression item) { - return ExpressionTool.GetMethodName(item) == "ToList" && IsSubquery(item); + return ExpressionTool.GetMethodName(item).IsIn("ToList","First") && IsSubquery(item); } private static bool IsSubquery(Expression item) diff --git a/Src/Asp.Net/SqlSugar/ExpressionsToSql/Subquery/Items/SubFirst.cs b/Src/Asp.Net/SqlSugar/ExpressionsToSql/Subquery/Items/SubFirst.cs new file mode 100644 index 000000000..43065de59 --- /dev/null +++ b/Src/Asp.Net/SqlSugar/ExpressionsToSql/Subquery/Items/SubFirst.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace SqlSugar +{ + public class SubFirst : ISubOperation + { + public bool HasWhere + { + get; set; + } + + public string Name + { + get + { + return "First"; + } + } + + public Expression Expression + { + get; set; + } + + + public int Sort + { + get + { + return 200; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression = null) + { + ; + var exp = expression as MethodCallExpression; + InitType(exp); + var type = expression.Type; + if (type.FullName.IsCollectionsList() + && exp.Arguments.Count == 0 && type.GenericTypeArguments.Length > 0 + && this.Context.SugarContext != null + && this.Context.SugarContext.QueryBuilder.IsSelectNoAll) + { + var entity = type.GenericTypeArguments[0]; + var columnNames = this.Context.SugarContext.Context.EntityMaintenance.GetEntityInfo(entity).Columns; + var columnsString = string.Join(",", columnNames + .Where(it => it.IsIgnore == false) + .Where(it => it.DbColumnName.HasValue()) + .Select(it => this.Context.GetTranslationColumnName(it.DbColumnName))); + return $"{columnsString},@sugarIndex as sugarIndex"; + } + else if (exp.Arguments.Count == 0) + { + return "*,@sugarIndex as sugarIndex"; + } + var argExp = exp.Arguments[0]; + var parametres = (argExp as LambdaExpression).Parameters; + if ((argExp as LambdaExpression).Body is UnaryExpression) + { + argExp = ((argExp as LambdaExpression).Body as UnaryExpression).Operand; + } + var argLambda = argExp as LambdaExpression; + var copyContext = this.Context.GetCopyContextWithMapping(); + copyContext.Resolve(argLambda, ResolveExpressType.SelectMultiple); + var select = copyContext.Result.GetString(); + this.Context.Parameters.AddRange(copyContext.Parameters); + this.Context.Index = copyContext.Index; + this.Context.ParameterIndex = copyContext.ParameterIndex; + SetShortName(exp, null); + return select + ",@sugarIndex as sugarIndex"; + } + + private void InitType(MethodCallExpression exp) + { + if (exp.Arguments.Count > 0) + { + foreach (var arg in (exp.Arguments[0] as LambdaExpression).Parameters) + { + if (this.Context.InitMappingInfo != null) + { + this.Context.InitMappingInfo(arg.Type); + this.Context.RefreshMapping(); + } + } + } + } + + public void SetShortName(MethodCallExpression exp, string result) + { + if (exp.Arguments[0] is LambdaExpression) + { + var parameters = (exp.Arguments[0] as LambdaExpression).Parameters; + if (parameters != null && parameters.Count > 0) + { + this.Context.CurrentShortName = this.Context.GetTranslationColumnName(parameters[0].ObjToString()); + } + + } + } + public void SetShortNameNext(MethodCallExpression exp, string result) + { + if (exp.Arguments.Count > 1 && exp.Arguments[1] is LambdaExpression) + { + var parameters = (exp.Arguments[1] as LambdaExpression).Parameters; + if (parameters != null && parameters.Count > 0) + { + this.Context.CurrentShortName = this.Context.GetTranslationColumnName(parameters[0].ObjToString()); + } + + } + } + } +} diff --git a/Src/Asp.Net/SqlSugar/ExpressionsToSql/Subquery/SubResolve.cs b/Src/Asp.Net/SqlSugar/ExpressionsToSql/Subquery/SubResolve.cs index a5ccfca4b..e326332b3 100644 --- a/Src/Asp.Net/SqlSugar/ExpressionsToSql/Subquery/SubResolve.cs +++ b/Src/Asp.Net/SqlSugar/ExpressionsToSql/Subquery/SubResolve.cs @@ -223,7 +223,7 @@ namespace SqlSugar }).ToList(); SetOrderByIndex(isubList); isubList.Insert(0, new SubBegin()); - if (isubList.Any(it => it is SubSelect)) + if (isubList.Any(it => it is SubSelect||it is SubFirst)) { isubList.Add(new SubTop() { Context = this.context }); } diff --git a/Src/Asp.Net/SqlSugar/ExpressionsToSql/Subquery/SubTools.cs b/Src/Asp.Net/SqlSugar/ExpressionsToSql/Subquery/SubTools.cs index 8ad4a2740..c8818cfcc 100644 --- a/Src/Asp.Net/SqlSugar/ExpressionsToSql/Subquery/SubTools.cs +++ b/Src/Asp.Net/SqlSugar/ExpressionsToSql/Subquery/SubTools.cs @@ -38,7 +38,8 @@ namespace SqlSugar new SubEnableTableFilter(){ Context=Context }, new SubSelectStringJoin{ Context=Context }, new SubDistinctCount{ Context=Context }, - new SubToList{ Context=Context} + new SubToList{ Context=Context}, + new SubFirst(){ Context=Context } }; } diff --git a/Src/Asp.Net/SqlSugar/ExpressionsToSql/Subquery/Subquerable.cs b/Src/Asp.Net/SqlSugar/ExpressionsToSql/Subquery/Subquerable.cs index d7520ad57..3dd5be98b 100644 --- a/Src/Asp.Net/SqlSugar/ExpressionsToSql/Subquery/Subquerable.cs +++ b/Src/Asp.Net/SqlSugar/ExpressionsToSql/Subquery/Subquerable.cs @@ -180,5 +180,10 @@ namespace SqlSugar { return null; } + + public T First() + { + return default(T); + } } } diff --git a/Src/Asp.Net/SqlSugar/SqlSugar.csproj b/Src/Asp.Net/SqlSugar/SqlSugar.csproj index d26d3d545..08f89d2d1 100644 --- a/Src/Asp.Net/SqlSugar/SqlSugar.csproj +++ b/Src/Asp.Net/SqlSugar/SqlSugar.csproj @@ -154,6 +154,7 @@ +