diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/AdoProvider/AdoProvider.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/AdoProvider/AdoProvider.cs index d03f76b23..808841c0b 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/AdoProvider/AdoProvider.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/AdoProvider/AdoProvider.cs @@ -227,16 +227,26 @@ namespace SqlSugar #region Core public virtual int ExecuteCommand(string sql, params SugarParameter[] parameters) { - if (this.ProcessingEventStartingSQL != null) - ExecuteProcessingSQL(ref sql, parameters); - ExecuteBefore(sql, parameters); - IDbCommand sqlCommand = GetCommand(sql, parameters); - int count = sqlCommand.ExecuteNonQuery(); - if (this.IsClearParameters) - sqlCommand.Parameters.Clear(); - ExecuteAfter(sql, parameters); - if (this.Context.CurrentConnectionConfig.IsAutoCloseConnection && this.Transaction == null) this.Close(); - return count; + try + { + if (this.ProcessingEventStartingSQL != null) + ExecuteProcessingSQL(ref sql, parameters); + ExecuteBefore(sql, parameters); + IDbCommand sqlCommand = GetCommand(sql, parameters); + int count = sqlCommand.ExecuteNonQuery(); + if (this.IsClearParameters) + sqlCommand.Parameters.Clear(); + ExecuteAfter(sql, parameters); + return count; + } + catch (Exception ex) + { + throw ex; + } + finally + { + if (this.IsClose()) this.Close(); + } } public virtual IDataReader GetDataReader(string sql, params SugarParameter[] parameters) { @@ -245,8 +255,7 @@ namespace SqlSugar ExecuteProcessingSQL(ref sql, parameters); ExecuteBefore(sql, parameters); IDbCommand sqlCommand = GetCommand(sql, parameters); - var isAutoClose = this.Context.CurrentConnectionConfig.IsAutoCloseConnection && this.Transaction == null; - IDataReader sqlDataReader = sqlCommand.ExecuteReader(isAutoClose ? CommandBehavior.CloseConnection : CommandBehavior.Default); + IDataReader sqlDataReader = sqlCommand.ExecuteReader(this.IsClose() ? CommandBehavior.CloseConnection : CommandBehavior.Default); if (isSp) DataReaderParameters = sqlCommand.Parameters; if (this.IsClearParameters) @@ -256,33 +265,53 @@ namespace SqlSugar } public virtual DataSet GetDataSetAll(string sql, params SugarParameter[] parameters) { - if (this.ProcessingEventStartingSQL != null) - ExecuteProcessingSQL(ref sql, parameters); - ExecuteBefore(sql, parameters); - IDataAdapter dataAdapter = this.GetAdapter(); - IDbCommand sqlCommand = GetCommand(sql, parameters); - this.SetCommandToAdapter(dataAdapter, sqlCommand); - DataSet ds = new DataSet(); - dataAdapter.Fill(ds); - if (this.IsClearParameters) - sqlCommand.Parameters.Clear(); - ExecuteAfter(sql, parameters); - if (this.Context.CurrentConnectionConfig.IsAutoCloseConnection && this.Transaction == null) this.Close(); - return ds; + try + { + if (this.ProcessingEventStartingSQL != null) + ExecuteProcessingSQL(ref sql, parameters); + ExecuteBefore(sql, parameters); + IDataAdapter dataAdapter = this.GetAdapter(); + IDbCommand sqlCommand = GetCommand(sql, parameters); + this.SetCommandToAdapter(dataAdapter, sqlCommand); + DataSet ds = new DataSet(); + dataAdapter.Fill(ds); + if (this.IsClearParameters) + sqlCommand.Parameters.Clear(); + ExecuteAfter(sql, parameters); + return ds; + } + catch (Exception ex) + { + throw ex; + } + finally + { + if (this.IsClose()) this.Close(); + } } public virtual object GetScalar(string sql, params SugarParameter[] parameters) { - if (this.ProcessingEventStartingSQL != null) - ExecuteProcessingSQL(ref sql, parameters); - ExecuteBefore(sql, parameters); - IDbCommand sqlCommand = GetCommand(sql, parameters); - object scalar = sqlCommand.ExecuteScalar(); - scalar = (scalar == null ? 0 : scalar); - if (this.IsClearParameters) - sqlCommand.Parameters.Clear(); - ExecuteAfter(sql, parameters); - if (this.Context.CurrentConnectionConfig.IsAutoCloseConnection && this.Transaction == null) this.Close(); - return scalar; + try + { + if (this.ProcessingEventStartingSQL != null) + ExecuteProcessingSQL(ref sql, parameters); + ExecuteBefore(sql, parameters); + IDbCommand sqlCommand = GetCommand(sql, parameters); + object scalar = sqlCommand.ExecuteScalar(); + scalar = (scalar == null ? 0 : scalar); + if (this.IsClearParameters) + sqlCommand.Parameters.Clear(); + ExecuteAfter(sql, parameters); + return scalar; + } + catch (Exception ex) + { + throw ex; + } + finally + { + if (this.IsClose()) this.Close(); + } } #endregion @@ -603,6 +632,10 @@ namespace SqlSugar if (parameters == null) return null; return base.GetParameters(parameters, propertyInfo, this.SqlParameterKeyWord); } + private bool IsClose() + { + return this.Context.CurrentConnectionConfig.IsAutoCloseConnection && this.Transaction == null; + } #endregion } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs index 9983c2d56..b54b2a74f 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs @@ -1078,6 +1078,7 @@ namespace SqlSugar asyncQueryableBuilder.Parameters = this.QueryBuilder.Parameters; asyncQueryableBuilder.TableShortName = this.QueryBuilder.TableShortName; asyncQueryableBuilder.TableWithString = this.QueryBuilder.TableWithString; + asyncQueryableBuilder.GroupByValue = this.QueryBuilder.GroupByValue; return asyncQueryable; } #endregion diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/SqlBuilderProvider/QueryBuilder.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/SqlBuilderProvider/QueryBuilder.cs index 0c8761cd4..9ee401be1 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/SqlBuilderProvider/QueryBuilder.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/SqlBuilderProvider/QueryBuilder.cs @@ -219,12 +219,18 @@ namespace SqlSugar resolveExpress.Resolve(expression, resolveType); this.Parameters.AddRange(resolveExpress.Parameters); var reval = resolveExpress.Result; + var isSingleTableHasSubquery = IsSingle() && resolveExpress.SingleTableNameSubqueryShortName.IsValuable(); + if (isSingleTableHasSubquery) { + Check.Exception(!string.IsNullOrEmpty(this.TableShortName) && resolveExpress.SingleTableNameSubqueryShortName != this.TableShortName, "{0} and {1} need same name"); + this.TableShortName = resolveExpress.SingleTableNameSubqueryShortName; + } return reval; } public virtual string ToSqlString() { string oldOrderBy = this.OrderByValue; string externalOrderBy = oldOrderBy; + var isIgnoreOrderBy = this.IsCount&&this.PartitionByValue.IsNullOrEmpty(); AppendFilter(); sql = new StringBuilder(); if (this.OrderByValue == null && (Skip != null || Take != null)) this.OrderByValue = " ORDER BY GetDate() "; @@ -236,10 +242,10 @@ namespace SqlSugar var rowNumberString = string.Format(",ROW_NUMBER() OVER({0}) AS RowIndex ", GetOrderByString); string groupByValue = GetGroupByString + HavingInfos; string orderByValue = (!isRowNumber && this.OrderByValue.IsValuable()) ? GetOrderByString : null; - if (this.IsCount) { orderByValue = null; } + if (isIgnoreOrderBy) { orderByValue = null; } sql.AppendFormat(SqlTemplate, GetSelectValue, GetTableNameString, GetWhereValueString, groupByValue, orderByValue); - sql.Replace(UtilConstants.ReplaceKey, isRowNumber ? (this.IsCount ? null : rowNumberString) : null); - if (this.IsCount) { this.OrderByValue = oldOrderBy; return sql.ToString(); } + sql.Replace(UtilConstants.ReplaceKey, isRowNumber ? (isIgnoreOrderBy ? null : rowNumberString) : null); + if (isIgnoreOrderBy) { this.OrderByValue = oldOrderBy; return sql.ToString(); } var result = ToPageSql(sql.ToString(), this.Take, this.Skip); if (ExternalPageIndex > 0) { @@ -445,7 +451,7 @@ namespace SqlSugar get { if (this.OrderByValue == null) return null; - if (IsCount) return null; + if (IsCount&&this.PartitionByValue.IsNullOrEmpty()) return null; else { return this.OrderByValue; diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Common/ExpressionParameter.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Common/ExpressionParameter.cs index fa49b7cd7..beab94221 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Common/ExpressionParameter.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Common/ExpressionParameter.cs @@ -36,5 +36,12 @@ namespace SqlSugar return this.IsLeft == true ? this.BaseParameter.RightExpression : this.BaseParameter.LeftExpression; } } + public bool IsSetTempData + { + get + { + return BaseParameter.CommonTempData.IsValuable() && BaseParameter.CommonTempData.Equals(CommonTempDataType.Result); + } + } } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Common/ExpressionResult.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Common/ExpressionResult.cs index 5d24e5f54..afe596dc9 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Common/ExpressionResult.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Common/ExpressionResult.cs @@ -52,6 +52,12 @@ namespace SqlSugar _Result = value; } } + public bool LastCharIsSpace{ + get { + if (_Result == null|| _Result.Length==0) return true; + return _Result.ToString().Last() == UtilConstants.SpaceChar; + } + } #endregion public string GetString() { diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/DbMethods/DefaultDbMethod.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/DbMethods/DefaultDbMethod.cs index 835e212bf..d6edde71e 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/DbMethods/DefaultDbMethod.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/DbMethods/DefaultDbMethod.cs @@ -294,5 +294,20 @@ namespace SqlSugar { return string.Join("", strings); } + + public virtual string Pack(string sql) + { + return "(" + sql + ")"; + } + + public virtual string EqualTrue(string fieldName) + { + return "( " + fieldName + "=1 )"; + } + + public virtual string Null() + { + return "NULL"; + } } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/DbMethods/IDbMethods.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/DbMethods/IDbMethods.cs index 88e72ffb3..1246de45f 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/DbMethods/IDbMethods.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/DbMethods/IDbMethods.cs @@ -24,6 +24,7 @@ namespace SqlSugar string DateIsSameDay(MethodCallExpressionModel model); string DateIsSameByType(MethodCallExpressionModel model); string DateAddByType(MethodCallExpressionModel model); + string DateValue(MethodCallExpressionModel model); string DateAddDay(MethodCallExpressionModel model); string Between(MethodCallExpressionModel model); @@ -52,5 +53,8 @@ namespace SqlSugar string False(); string GuidNew(); string MergeString(params string[] strings); + string EqualTrue(string value); + string Pack(string sql); + string Null(); } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/DbMethods/SqlFunc.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/DbMethods/SqlFunc.cs index f0a00ccc6..4da350ffe 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/DbMethods/SqlFunc.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/DbMethods/SqlFunc.cs @@ -102,5 +102,11 @@ namespace SqlSugar /// /// public static TResult GetSelfAndAutoFill(TResult value) { throw new NotSupportedException("Can only be used in expressions"); } + /// + /// Subquery + /// + /// + /// + public static Subqueryable Subqueryable() where T:class,new(){ throw new NotSupportedException("Can only be used in expressions");} } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ExpressionContext.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ExpressionContext.cs index a378b2b42..ffcfabbd6 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ExpressionContext.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ExpressionContext.cs @@ -37,6 +37,7 @@ namespace SqlSugar } public int Index { get; set; } public int ParameterIndex { get; set; } + public string SingleTableNameSubqueryShortName{ get; set; } public MappingColumnList MappingColumns { get; set; } public MappingTableList MappingTables { get; set; } public IgnoreColumnList IgnoreComumnList { get; set; } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/BaseResolve.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/BaseResolve.cs index 0133e1026..f74b5ab23 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/BaseResolve.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/BaseResolve.cs @@ -54,7 +54,7 @@ namespace SqlSugar } else if (expression is ConditionalExpression) { - Check.ThrowNotSupportedException("ConditionalExpression"); + return new ConditionalExpressionResolve(parameter); } else if (expression is MethodCallExpression) { @@ -239,9 +239,10 @@ namespace SqlSugar protected void AppendNot(object Value) { var isAppend = !this.Context.Result.Contains(ExpressionConst.FormatSymbol); + var lastCharIsSpace = this.Context.Result.LastCharIsSpace; if (isAppend) { - this.Context.Result.Append("NOT"); + this.Context.Result.Append(lastCharIsSpace?"NOT":" NOT"); } else { diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/ConditionalExpressionResolve.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/ConditionalExpressionResolve.cs index 4f1719e2a..85e81bca6 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/ConditionalExpressionResolve.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/ConditionalExpressionResolve.cs @@ -9,7 +9,25 @@ namespace SqlSugar { public ConditionalExpressionResolve(ExpressionParameter parameter) : base(parameter) { - + var express = base.Expression as ConditionalExpression; + var isLeft = parameter.IsLeft; + switch (base.Context.ResolveType) + { + case ResolveExpressType.None: + case ResolveExpressType.WhereSingle: + case ResolveExpressType.WhereMultiple: + case ResolveExpressType.SelectSingle: + case ResolveExpressType.SelectMultiple: + case ResolveExpressType.FieldSingle: + case ResolveExpressType.FieldMultiple: + case ResolveExpressType.Join: + case ResolveExpressType.ArraySingle: + case ResolveExpressType.ArrayMultiple: + case ResolveExpressType.Update: + default: + Check.Exception(true, "Does not support it.xx==value ? true:false , Use SqlFunc.IIF (it.xx==value,true,false)"); + break; + } } } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/ConstantExpressionResolve.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/ConstantExpressionResolve.cs index 3d1cdf688..c06a56904 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/ConstantExpressionResolve.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/ConstantExpressionResolve.cs @@ -55,7 +55,7 @@ namespace SqlSugar if (value == null && parentIsBinary) { parameter.BaseParameter.ValueIsNull = true; - value = "NULL"; + value = this.Context.DbMehtods.Null(); } AppendValue(parameter, isLeft, value); } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/MemberExpressionResolve.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/MemberExpressionResolve.cs index 684a7b21f..f53d9e5fa 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/MemberExpressionResolve.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/MemberExpressionResolve.cs @@ -11,205 +11,247 @@ namespace SqlSugar public MemberExpressionResolve(ExpressionParameter parameter) : base(parameter) { var baseParameter = parameter.BaseParameter; - var isLeft = parameter.IsLeft; - var isSetTempData = baseParameter.CommonTempData.IsValuable() && baseParameter.CommonTempData.Equals(CommonTempDataType.Result); var expression = base.Expression as MemberExpression; var childExpression = expression.Expression as MemberExpression; + var memberName = expression.Member.Name; var childIsMember = childExpression != null; - var isValue = expression.Member.Name == "Value" && expression.Member.DeclaringType.Name == "Nullable`1"; + var isLeft = parameter.IsLeft; + var isSetTempData = parameter.IsSetTempData; + var isValue = memberName == "Value" && expression.Member.DeclaringType.Name == "Nullable`1"; var isBool = expression.Type == UtilConstants.BoolType; var isValueBool = isValue && isBool && parameter.BaseExpression == null; - var isLength = expression.Member.Name == "Length" && childIsMember && childExpression.Type == UtilConstants.StringType; - var isDateValue = expression.Member.Name.IsIn(Enum.GetNames(typeof(DateType))) && (expression.Expression as MemberExpression).Type == UtilConstants.DateType; + var isLength = memberName == "Length" && childIsMember && childExpression.Type == UtilConstants.StringType; + var isDateValue = memberName.IsIn(Enum.GetNames(typeof(DateType))) && (expression.Expression as MemberExpression).Type == UtilConstants.DateType; var isLogicOperator = ExpressionTool.IsLogicOperator(baseParameter.OperatorValue) || baseParameter.OperatorValue.IsNullOrEmpty(); - var isHasValue = isLogicOperator && expression.Member.Name == "HasValue" && expression.Expression != null && expression.NodeType == ExpressionType.MemberAccess; - var isDateTimeNowDate = expression.Member.Name == "Date" && childIsMember && childExpression.Member.Name == "Now"; - var isDateDate = expression.Member.Name == "Date" && expression.Expression.Type == UtilConstants.DateType; + var isHasValue = isLogicOperator && memberName == "HasValue" && expression.Expression != null && expression.NodeType == ExpressionType.MemberAccess; + var isDateDate = memberName == "Date" && expression.Expression.Type == UtilConstants.DateType; + var isMemberValue = expression.Expression != null && expression.Expression.NodeType != ExpressionType.Parameter && !isValueBool; + var isSingle = parameter.Context.ResolveType == ResolveExpressType.WhereSingle; + if (isLength) { - var oldCommonTempDate = parameter.CommonTempData; - parameter.CommonTempData = CommonTempDataType.Result; - this.Expression = expression.Expression; - var isConst = this.Expression is ConstantExpression; - this.Start(); - var methodParamter = new MethodCallExpressionArgs() { IsMember = !isConst, MemberName = parameter.CommonTempData, MemberValue = null }; - var result = this.Context.DbMehtods.Length(new MethodCallExpressionModel() - { - Args = new List() { - methodParamter - } - }); - base.AppendMember(parameter, isLeft, result); - parameter.CommonTempData = oldCommonTempDate; - return; + ResolveLength(parameter, isLeft, expression); } else if (isHasValue) { - parameter.CommonTempData = CommonTempDataType.Result; - this.Expression = expression.Expression; - this.Start(); - var methodParamter = new MethodCallExpressionArgs() { IsMember = true, MemberName = parameter.CommonTempData, MemberValue = null }; - var result = this.Context.DbMehtods.HasValue(new MethodCallExpressionModel() - { - Args = new List() { - methodParamter - } - }); - this.Context.Result.Append(result); - parameter.CommonTempData = null; - return; + ResolveHasValue(parameter, expression); } else if (isDateValue) { - var name = expression.Member.Name; - var oldCommonTempDate = parameter.CommonTempData; - parameter.CommonTempData = CommonTempDataType.Result; - this.Expression = expression.Expression; - var isConst = this.Expression is ConstantExpression; - this.Start(); - var result = this.Context.DbMehtods.DateValue(new MethodCallExpressionModel() - { - Args = new List() { - new MethodCallExpressionArgs() { IsMember = !isConst, MemberName = parameter.CommonTempData, MemberValue = null }, - new MethodCallExpressionArgs() { IsMember = true, MemberName = name, MemberValue = name } - } - }); - base.AppendMember(parameter, isLeft, result); - parameter.CommonTempData = oldCommonTempDate; - return; + ResolveDateValue(parameter, isLeft, expression); } else if (isValueBool) { - isValue = false; + ResolveValueBool(parameter, baseParameter, expression, isLeft, isSingle); } else if (isValue) { - expression = expression.Expression as MemberExpression; + ResolveValue(parameter, baseParameter, expression, isLeft, isSetTempData, isSingle); } else if (isDateDate) { - var name = expression.Member.Name; - var oldCommonTempDate = parameter.CommonTempData; - parameter.CommonTempData = CommonTempDataType.Result; - this.Expression = expression.Expression; - this.Start(); - var isConst = parameter.CommonTempData.GetType() == UtilConstants.DateType; - if (isConst) - { - AppendValue(parameter, isLeft, parameter.CommonTempData.ObjToDate().Date); - } - else - { - var GetYear = new MethodCallExpressionModel() - { - Args = new List() { - new MethodCallExpressionArgs() { IsMember=true, MemberName=parameter.CommonTempData, MemberValue=parameter.CommonTempData }, - new MethodCallExpressionArgs() { MemberName=DateType.Year, MemberValue=DateType.Year} - } - }; - AppendMember(parameter, isLeft, GetToDate(this.Context.DbMehtods.MergeString( - this.GetDateValue(parameter.CommonTempData, DateType.Year), - "+'-'+", - this.GetDateValue(parameter.CommonTempData, DateType.Month), - "+'-'+", - this.GetDateValue(parameter.CommonTempData, DateType.Day)))); - } - parameter.CommonTempData = oldCommonTempDate; - return; + ResolveDateDate(parameter, isLeft, expression); } - else if (isDateTimeNowDate) + else if (isMemberValue) { - AppendValue(parameter, isLeft, DateTime.Now.Date); - return; + ResolveMemberValue(parameter, baseParameter, isLeft, isSetTempData, expression); } - else if (expression.Expression != null && expression.Expression.NodeType != ExpressionType.Parameter && !isValueBool) + else { - var value = ExpressionTool.GetMemberValue(expression.Member, expression); - if (isSetTempData) + baseParameter.ChildExpression = expression; + string fieldName = string.Empty; + switch (parameter.Context.ResolveType) { - baseParameter.CommonTempData = value; - } - else - { - AppendValue(parameter, isLeft, value); - } - return; - } - string fieldName = string.Empty; - baseParameter.ChildExpression = expression; - switch (parameter.Context.ResolveType) - { - case ResolveExpressType.SelectSingle: - fieldName = GetSingleName(parameter, expression, isLeft); - if (isSetTempData) - { - baseParameter.CommonTempData = fieldName; - } - else - { - base.Context.Result.Append(fieldName); - } - break; - case ResolveExpressType.SelectMultiple: - fieldName = GetMultipleName(parameter, expression, isLeft); - if (isSetTempData) - { - baseParameter.CommonTempData = fieldName; - } - else - { - base.Context.Result.Append(fieldName); - } - break; - case ResolveExpressType.WhereSingle: - case ResolveExpressType.WhereMultiple: - var isSingle = parameter.Context.ResolveType == ResolveExpressType.WhereSingle; - if (isSetTempData) - { - fieldName = GetName(parameter, expression, null, isSingle); - baseParameter.CommonTempData = fieldName; - } - else - { - if (isValueBool) - { - fieldName = GetName(parameter, expression.Expression as MemberExpression, isLeft, isSingle); - } - else if (ExpressionTool.IsConstExpression(expression)) - { - var value = ExpressionTool.GetMemberValue(expression.Member, expression); - base.AppendValue(parameter, isLeft, value); - return; - } + case ResolveExpressType.SelectSingle: + fieldName = GetSingleName(parameter, expression, isLeft); + if (isSetTempData) + baseParameter.CommonTempData = fieldName; else - { - fieldName = GetName(parameter, expression, isLeft, isSingle); - } - if (expression.Type == UtilConstants.BoolType && baseParameter.OperatorValue.IsNullOrEmpty()) - { - fieldName = "( " + fieldName + "=1 )"; - } - fieldName = AppendMember(parameter, isLeft, fieldName); - } - break; - case ResolveExpressType.FieldSingle: - fieldName = GetSingleName(parameter, expression, isLeft); - base.Context.Result.Append(fieldName); - break; - case ResolveExpressType.FieldMultiple: - fieldName = GetMultipleName(parameter, expression, isLeft); - base.Context.Result.Append(fieldName); - break; - case ResolveExpressType.ArrayMultiple: - case ResolveExpressType.ArraySingle: - fieldName = GetName(parameter, expression, isLeft, parameter.Context.ResolveType == ResolveExpressType.ArraySingle); - base.Context.Result.Append(fieldName); - break; - default: - break; + base.Context.Result.Append(fieldName); + break; + case ResolveExpressType.SelectMultiple: + fieldName = GetMultipleName(parameter, expression, isLeft); + if (isSetTempData) + baseParameter.CommonTempData = fieldName; + else + base.Context.Result.Append(fieldName); + break; + case ResolveExpressType.WhereSingle: + case ResolveExpressType.WhereMultiple: + ResolveWhereLogic(parameter, baseParameter, expression, isLeft, isSetTempData, isSingle); + break; + case ResolveExpressType.FieldSingle: + fieldName = GetSingleName(parameter, expression, isLeft); + base.Context.Result.Append(fieldName); + break; + case ResolveExpressType.FieldMultiple: + fieldName = GetMultipleName(parameter, expression, isLeft); + base.Context.Result.Append(fieldName); + break; + case ResolveExpressType.ArrayMultiple: + case ResolveExpressType.ArraySingle: + fieldName = GetName(parameter, expression, isLeft, parameter.Context.ResolveType == ResolveExpressType.ArraySingle); + base.Context.Result.Append(fieldName); + break; + default: + break; + } } } + #region Resolve Where + private void ResolveWhereLogic(ExpressionParameter parameter, ExpressionParameter baseParameter, MemberExpression expression, bool? isLeft, bool isSetTempData, bool isSingle) + { + string fieldName = string.Empty; + if (isSetTempData) + { + if (ExpressionTool.IsConstExpression(expression)) + { + var value = ExpressionTool.GetMemberValue(expression.Member, expression); + base.AppendValue(parameter, isLeft, value); + } + else + { + fieldName = GetName(parameter, expression, null, isSingle); + baseParameter.CommonTempData = fieldName; + } + } + else + { + if (ExpressionTool.IsConstExpression(expression)) + { + var value = ExpressionTool.GetMemberValue(expression.Member, expression); + base.AppendValue(parameter, isLeft, value); + return; + } + fieldName = GetName(parameter, expression, isLeft, isSingle); + if (expression.Type == UtilConstants.BoolType && baseParameter.OperatorValue.IsNullOrEmpty()) + { + fieldName = this.Context.DbMehtods.EqualTrue(fieldName); + } + AppendMember(parameter, isLeft, fieldName); + } + } + #endregion + + #region Resolve special member + private MemberExpression ResolveValue(ExpressionParameter parameter, ExpressionParameter baseParameter, MemberExpression expression, bool? isLeft, bool isSetTempData, bool isSingle) + { + expression = expression.Expression as MemberExpression; + baseParameter.ChildExpression = expression; + ResolveWhereLogic(parameter, baseParameter, expression, isLeft, isSetTempData, isSingle); + return expression; + } + + private void ResolveValueBool(ExpressionParameter parameter, ExpressionParameter baseParameter, MemberExpression expression, bool? isLeft, bool isSingle) + { + string fieldName = GetName(parameter, expression.Expression as MemberExpression, isLeft, isSingle); + if (expression.Type == UtilConstants.BoolType && baseParameter.OperatorValue.IsNullOrEmpty()) + { + fieldName = this.Context.DbMehtods.EqualTrue(fieldName); + } + AppendMember(parameter, isLeft, fieldName); + } + + private void ResolveMemberValue(ExpressionParameter parameter, ExpressionParameter baseParameter, bool? isLeft, bool isSetTempData, MemberExpression expression) + { + var value = ExpressionTool.GetMemberValue(expression.Member, expression); + if (isSetTempData) + { + baseParameter.CommonTempData = value; + } + else + { + AppendValue(parameter, isLeft, value); + } + } + + private void ResolveDateDate(ExpressionParameter parameter, bool? isLeft, MemberExpression expression) + { + var name = expression.Member.Name; + var oldCommonTempDate = parameter.CommonTempData; + parameter.CommonTempData = CommonTempDataType.Result; + this.Expression = expression.Expression; + this.Start(); + var isConst = parameter.CommonTempData.GetType() == UtilConstants.DateType; + if (isConst) + { + AppendValue(parameter, isLeft, parameter.CommonTempData.ObjToDate().Date); + } + else + { + var GetYear = new MethodCallExpressionModel() + { + Args = new List() { + new MethodCallExpressionArgs() { IsMember=true, MemberName=parameter.CommonTempData, MemberValue=parameter.CommonTempData }, + new MethodCallExpressionArgs() { MemberName=DateType.Year, MemberValue=DateType.Year} + } + }; + AppendMember(parameter, isLeft, GetToDate(this.Context.DbMehtods.MergeString( + this.GetDateValue(parameter.CommonTempData, DateType.Year), + "+'-'+", + this.GetDateValue(parameter.CommonTempData, DateType.Month), + "+'-'+", + this.GetDateValue(parameter.CommonTempData, DateType.Day)))); + } + parameter.CommonTempData = oldCommonTempDate; + } + + private void ResolveDateValue(ExpressionParameter parameter, bool? isLeft, MemberExpression expression) + { + var name = expression.Member.Name; + var oldCommonTempDate = parameter.CommonTempData; + parameter.CommonTempData = CommonTempDataType.Result; + this.Expression = expression.Expression; + var isConst = this.Expression is ConstantExpression; + this.Start(); + var result = this.Context.DbMehtods.DateValue(new MethodCallExpressionModel() + { + Args = new List() { + new MethodCallExpressionArgs() { IsMember = !isConst, MemberName = parameter.CommonTempData, MemberValue = null }, + new MethodCallExpressionArgs() { IsMember = true, MemberName = name, MemberValue = name } + } + }); + base.AppendMember(parameter, isLeft, result); + parameter.CommonTempData = oldCommonTempDate; + } + + private void ResolveHasValue(ExpressionParameter parameter, MemberExpression expression) + { + parameter.CommonTempData = CommonTempDataType.Result; + this.Expression = expression.Expression; + this.Start(); + var methodParamter = new MethodCallExpressionArgs() { IsMember = true, MemberName = parameter.CommonTempData, MemberValue = null }; + var result = this.Context.DbMehtods.HasValue(new MethodCallExpressionModel() + { + Args = new List() { + methodParamter + } + }); + this.Context.Result.Append(result); + parameter.CommonTempData = null; + } + + private void ResolveLength(ExpressionParameter parameter, bool? isLeft, MemberExpression expression) + { + var oldCommonTempDate = parameter.CommonTempData; + parameter.CommonTempData = CommonTempDataType.Result; + this.Expression = expression.Expression; + var isConst = this.Expression is ConstantExpression; + this.Start(); + var methodParamter = new MethodCallExpressionArgs() { IsMember = !isConst, MemberName = parameter.CommonTempData, MemberValue = null }; + var result = this.Context.DbMehtods.Length(new MethodCallExpressionModel() + { + Args = new List() { + methodParamter + } + }); + base.AppendMember(parameter, isLeft, result); + parameter.CommonTempData = oldCommonTempDate; + } + #endregion + + #region Helper private string AppendMember(ExpressionParameter parameter, bool? isLeft, string fieldName) { if (parameter.BaseExpression is BinaryExpression || (parameter.BaseParameter.CommonTempData != null && parameter.BaseParameter.CommonTempData.Equals(CommonTempDataType.Append))) @@ -253,7 +295,7 @@ namespace SqlSugar string shortName = expression.Expression.ToString(); string fieldName = expression.Member.Name; fieldName = this.Context.GetDbColumnName(expression.Expression.Type.Name, fieldName); - fieldName = Context.GetTranslationColumnName(shortName + "." + fieldName); + fieldName = Context.GetTranslationColumnName(shortName +UtilConstants.Dot+ fieldName); return fieldName; } @@ -276,6 +318,7 @@ namespace SqlSugar }; return this.Context.DbMehtods.DateValue(pars); } + private string GetToDate(string value) { var pars = new MethodCallExpressionModel() @@ -286,5 +329,6 @@ namespace SqlSugar }; return this.Context.DbMehtods.ToDate(pars); } + #endregion } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs index d7c9e30f1..b66c17f8c 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs @@ -40,7 +40,22 @@ namespace SqlSugar this.Context.Result.Append(this.Context.DbMehtods.GuidNew()); return; } - if (!isValidNativeMethod && express.Method.DeclaringType.Namespace.IsIn("System.Linq", "System.Collections.Generic") && methodName == "Contains") + else if (IsSubMethod(express, methodName)) + { + //Check.Exception(!(parameter.BaseExpression is BinaryExpression), "Current expressions are not supported"); + SubResolve subResolve = new SubResolve(express, this.Context, parameter.OppsiteExpression); + var appendSql = subResolve.GetSql(); + if (this.Context.ResolveType.IsIn(ResolveExpressType.SelectMultiple,ResolveExpressType.SelectSingle)) + { + parameter.BaseParameter.CommonTempData = appendSql; + } + else + { + base.AppendValue(parameter, isLeft, appendSql); + } + return; + } + if (IsContainsArray(express, methodName, isValidNativeMethod)) { methodName = "ContainsArray"; isValidNativeMethod = true; @@ -117,7 +132,8 @@ namespace SqlSugar { this.Context.ResolveType = ResolveExpressType.WhereSingle; } - else { + else + { this.Context.ResolveType = ResolveExpressType.WhereMultiple; } Where(parameter, isLeft, name, args, model); @@ -140,7 +156,7 @@ namespace SqlSugar model.Args.AddRange(appendArgs); } } - if (parameter.BaseParameter.BaseParameter.BaseParameter==null) + if (parameter.BaseParameter.BaseParameter.BaseParameter == null) { this.Context.Result.Append(GetMdthodValue(name, model)); } @@ -167,7 +183,7 @@ namespace SqlSugar { var isBinaryExpression = item is BinaryExpression || item is MethodCallExpression; var isConst = item is ConstantExpression; - var isIIF= name == "IIF"; + var isIIF = name == "IIF"; var isIFFBoolMember = isIIF && (item is MemberExpression) && (item as MemberExpression).Type == UtilConstants.BoolType; var isIFFUnary = isIIF && (item is UnaryExpression) && (item as UnaryExpression).Operand.Type == UtilConstants.BoolType; var isIFFBoolBinary = isIIF && (item is BinaryExpression) && (item as BinaryExpression).Type == UtilConstants.BoolType; @@ -198,7 +214,8 @@ namespace SqlSugar AppendModelByIIFBinary(parameter, model, item); } - else if (isIFFBoolMethod && !isFirst) { + else if (isIFFBoolMethod && !isFirst) + { AppendModelByIIFMethod(parameter, model, item); } else if (isBinaryExpression) @@ -251,7 +268,7 @@ namespace SqlSugar private void AppendModelByIIFMethod(ExpressionParameter parameter, MethodCallExpressionModel model, Expression item) { var methodExpression = item as MethodCallExpression; - if (methodExpression.Method.Name.IsIn("ToBool", "ToBoolean","IIF")) + if (methodExpression.Method.Name.IsIn("ToBool", "ToBoolean", "IIF")) { model.Args.Add(base.GetMethodCallArgs(parameter, item)); } @@ -433,6 +450,15 @@ namespace SqlSugar { "AddMilliseconds",DateType.Millisecond} }; + private bool IsContainsArray(MethodCallExpression express, string methodName, bool isValidNativeMethod) + { + return !isValidNativeMethod && express.Method.DeclaringType.Namespace.IsIn("System.Linq", "System.Collections.Generic") && methodName == "Contains"; + } + + private bool IsSubMethod(MethodCallExpression express, string methodName) + { + return SubTools.SubItemsConst.Any(it => it.Name == methodName) && express.Object != null && express.Object.Type.Name == "Subqueryable`1"; + } private void CheckMethod(MethodCallExpression expression) { Check.Exception(expression.Method.ReflectedType().FullName != ExpressionConst.SqlFuncFullName, string.Format(ErrorMessage.MethodError, expression.Method.Name)); diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/ISubOperation.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/ISubOperation.cs new file mode 100644 index 000000000..b0848a862 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/ISubOperation.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace SqlSugar +{ + public interface ISubOperation + { + ExpressionContext Context { get; set; } + string Name { get; } + string GetValue(Expression expression); + int Sort { get; } + Expression Expression { get; set; } + } +} diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubAnd.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubAnd.cs new file mode 100644 index 000000000..e173876ca --- /dev/null +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubAnd.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace SqlSugar +{ + public class SubAnd:ISubOperation + { + public string Name + { + get { return "And"; } + } + + public Expression Expression + { + get; set; + } + + public int Sort + { + get + { + return 401; + } + } + + public ExpressionContext Context + { + get;set; + } + + public string GetValue(Expression expression) + { + var exp = expression as MethodCallExpression; + var argExp = exp.Arguments[0]; + var result = "AND " + SubTools.GetMethodValue(this.Context, argExp, ResolveExpressType.WhereMultiple); + var selfParameterName = this.Context.GetTranslationColumnName((argExp as LambdaExpression).Parameters.First().Name) + UtilConstants.Dot; + result = result.Replace(selfParameterName, string.Empty); + return result; + } + } +} diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubAny.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubAny.cs new file mode 100644 index 000000000..926791737 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubAny.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace SqlSugar +{ + public class SubAny : ISubOperation + { + public ExpressionContext Context + { + get;set; + } + + public Expression Expression + { + get;set; + } + + public string Name + { + get + { + return "Any"; + } + } + + public int Sort + { + get + { + return 0; + } + } + + public string GetValue(Expression expression) + { + return "EXISTS"; + } + } +} diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubBegin.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubBegin.cs new file mode 100644 index 000000000..9ddcf1c46 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubBegin.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace SqlSugar +{ + public class SubBegin : ISubOperation + { + public string Name + { + get + { + return "Begin"; + } + } + + public Expression Expression + { + get; set; + } + + public int Sort + { + get + { + return 100; + } + } + + public ExpressionContext Context + { + get;set; + } + + public string GetValue(Expression expression) + { + return "SELECT"; + } + } +} diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubCount.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubCount.cs new file mode 100644 index 000000000..199c0f744 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubCount.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace SqlSugar +{ + public class SubCount: ISubOperation + { + public string Name + { + get + { + return "Count"; + } + } + + public Expression Expression + { + get; set; + } + + + public int Sort + { + get + { + return 200; + } + } + + public ExpressionContext Context + { + get; set; + } + + public string GetValue(Expression expression) + { + return "COUNT(*)"; + } + } +} diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubFromTable.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubFromTable.cs new file mode 100644 index 000000000..7d2832817 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubFromTable.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace SqlSugar +{ + public class SubFromTable : ISubOperation + { + public string Name + { + get + { + return "Subqueryable"; + } + } + + public Expression Expression + { + get; set; + } + + public int Sort + { + get + { + return 300; + } + } + + public ExpressionContext Context + { + get;set; + } + + public string GetValue(Expression expression) + { + var exp = expression as MethodCallExpression; + var resType = exp.Method.ReturnType; + var name = resType.GetGenericArguments().First().Name; + return "FROM "+this.Context.GetTranslationTableName(name, true); + } + } +} diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubLeftBracket.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubLeftBracket.cs new file mode 100644 index 000000000..a770cd10c --- /dev/null +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubLeftBracket.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace SqlSugar +{ + public class SubLeftBracket : ISubOperation + { + public ExpressionContext Context + { + get;set; + } + + public Expression Expression + { + get;set; + } + + public string Name + { + get + { + return "LeftBracket"; + } + } + + public int Sort + { + get + { + return 50; + } + } + + public string GetValue(Expression expression) + { + return "("; + } + } +} diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubMax.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubMax.cs new file mode 100644 index 000000000..12c20bc5d --- /dev/null +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubMax.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace SqlSugar +{ + public class SubMax:ISubOperation + { + public string Name + { + get + { + return "Max"; + } + } + + 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; + return "MAX("+SubTools.GetMethodValue(this.Context, exp.Arguments[0], ResolveExpressType.FieldSingle)+")"; + } + } +} diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubMin.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubMin.cs new file mode 100644 index 000000000..32ae0285b --- /dev/null +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubMin.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace SqlSugar +{ + public class SubMin: ISubOperation + { + public string Name + { + get + { + return "Min"; + } + } + + 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; + return "MIN(" + SubTools.GetMethodValue(this.Context, exp.Arguments[0], ResolveExpressType.FieldSingle) + ")"; + } + } +} diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubNotAny.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubNotAny.cs new file mode 100644 index 000000000..b08db473d --- /dev/null +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubNotAny.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace SqlSugar +{ + public class SubNotAny : ISubOperation + { + public ExpressionContext Context + { + get;set; + } + + public Expression Expression + { + get; set; + } + + public string Name + { + get + { + return "NotAny"; + } + } + + public int Sort + { + get + { + return 0; + } + } + + public string GetValue(Expression expression) + { + return "NOT EXISTS"; + } + } +} diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubRightBracket.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubRightBracket.cs new file mode 100644 index 000000000..cb8f22287 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubRightBracket.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace SqlSugar +{ + public class SubRightBracket : ISubOperation + { + public ExpressionContext Context + { + get;set; + } + + public Expression Expression + { + get;set; + } + + public string Name + { + get + { + return "RightBracket"; + } + } + + public int Sort + { + get + { + return 500; + } + } + + public string GetValue(Expression expression) + { + return ")"; + } + } +} diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubSelect.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubSelect.cs new file mode 100644 index 000000000..9606dc608 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubSelect.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace SqlSugar +{ + public class SubSelect : ISubOperation + { + public string Name + { + get + { + return "Select"; + } + } + + 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; + return SubTools.GetMethodValue(this.Context, exp.Arguments[0],ResolveExpressType.FieldSingle); + } + } +} diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubSelectDefault.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubSelectDefault.cs new file mode 100644 index 000000000..b34236c43 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubSelectDefault.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace SqlSugar +{ + public class SubSelectDefault : ISubOperation + { + public ExpressionContext Context + { + get;set; + } + + public Expression Expression + { + get;set; + } + + public string Name + { + get { + return "SelectDefault"; + } + } + + public int Sort + { + get + { + return 250; + } + } + + public string GetValue(Expression expression) + { + return "*"; + } + } +} diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubTop.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubTop.cs new file mode 100644 index 000000000..dbb4427e8 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubTop.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace SqlSugar +{ + public class SubTop : ISubOperation + { + public ExpressionContext Context + { + get;set; + } + + public Expression Expression + { + get;set; + } + + public string Name + { + get + { + return "Top"; + } + } + + public int Sort + { + get + { + if (this.Context is SqlServerExpressionContext) + { + return 150; + } + else + { + return 450; + } + } + } + + + public string GetValue(Expression expression) + { + if (this.Context is SqlServerExpressionContext) + { + return "TOP 1"; + } + else { + return "limit 0,1"; + } + } + } +} diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubWhere.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubWhere.cs new file mode 100644 index 000000000..81046283a --- /dev/null +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Items/SubWhere.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace SqlSugar +{ + public class SubWhere: ISubOperation + { + public string Name + { + get { return "Where"; } + } + + public Expression Expression + { + get; set; + } + + public int Sort + { + get + { + return 400; + } + } + + public ExpressionContext Context + { + get;set; + } + + public string GetValue(Expression expression) + { + var exp = expression as MethodCallExpression; + var argExp= exp.Arguments[0]; + var result= "WHERE "+SubTools.GetMethodValue(Context, argExp, ResolveExpressType.WhereMultiple); + var selfParameterName = Context.GetTranslationColumnName((argExp as LambdaExpression).Parameters.First().Name)+UtilConstants.Dot; + result = result.Replace(selfParameterName,string.Empty); + return result; + } + } +} diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/SubResolve.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/SubResolve.cs new file mode 100644 index 000000000..acb5c29ac --- /dev/null +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/SubResolve.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace SqlSugar +{ + /// + /// ** description:Get subquery sql + /// ** author:sunkaixuan + /// ** date:2017/9/17 + /// ** email:610262374@qq.com + /// + public class SubResolve + { + List allMethods = new List(); + private ExpressionContext context = null; + private bool hasWhere; + public SubResolve(MethodCallExpression expression, ExpressionContext context, Expression oppsiteExpression) + { + this.context = context; + var currentExpression = expression; + allMethods.Add(currentExpression); + if (context.IsSingle && oppsiteExpression != null&& oppsiteExpression is MemberExpression) + { + var childExpression = (oppsiteExpression as MemberExpression).Expression; + this.context.SingleTableNameSubqueryShortName = (childExpression as ParameterExpression).Name; + } + else if (context.IsSingle) + { + this.context.SingleTableNameSubqueryShortName = (context.Expression as LambdaExpression).Parameters.First().Name; + } + while (currentExpression != null) + { + var addItem = currentExpression.Object as MethodCallExpression; + if (addItem != null) + allMethods.Add(addItem); + currentExpression = addItem; + } + } + + public string GetSql() + { + List subItems = GetSubItems(); + var sql = string.Join(UtilConstants.Space, subItems); + return this.context.DbMehtods.Pack(sql); + } + + private List GetSubItems() + { + var isubList = this.allMethods.Select(exp => + { + var methodName = exp.Method.Name; + var items = SubTools.SubItems(this.context); + var item = items.First(s => s.Name == methodName); + if (item is SubWhere && hasWhere == false) + { + hasWhere = true; + } + else if (item is SubWhere) + { + item = items.First(s => s is SubAnd); + } + item.Context = this.context; + item.Expression = exp; + return item; + }).ToList(); + isubList.Insert(0, new SubBegin()); + if (isubList.Any(it => it is SubSelect)) + { + isubList.Add(new SubTop() { Context=this.context }); + } + if (isubList.Any(it => it is SubAny || it is SubNotAny)) + { + isubList.Add(new SubLeftBracket()); + isubList.Add(new SubRightBracket()); + isubList.Add(new SubSelectDefault()); + } + isubList = isubList.OrderBy(it => it.Sort).ToList(); + List result = isubList.Select(it => + { + return it.GetValue(it.Expression); + }).ToList(); + return result; + } + } +} diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/SubTools.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/SubTools.cs new file mode 100644 index 000000000..33571f7cb --- /dev/null +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/SubTools.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace SqlSugar +{ + public class SubTools + { + public static List SubItems(ExpressionContext Context) + { + + return new List() + { + new SubSelect() { Context=Context }, + new SubWhere(){ Context=Context }, + new SubAnd(){ Context=Context }, + new SubAny(){ Context=Context }, + new SubNotAny(){ Context=Context }, + new SubBegin(){ Context=Context }, + new SubFromTable(){ Context=Context }, + new SubCount(){ Context=Context }, + new SubMax(){ Context=Context }, + new SubMin(){ Context=Context } + }; + } + + public static List SubItemsConst = SubItems(null); + + public static string GetMethodValue(ExpressionContext context, Expression item, ResolveExpressType type) + { + var newContext = context.GetCopyContext(); + newContext.MappingColumns = context.MappingColumns; + newContext.MappingTables = context.MappingTables; + newContext.IgnoreComumnList = context.IgnoreComumnList; + newContext.Resolve(item, type); + context.Index = newContext.Index; + context.ParameterIndex = newContext.ParameterIndex; + return newContext.Result.GetResultString(); + } + } +} diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Subquerable.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Subquerable.cs new file mode 100644 index 000000000..27254deb5 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/Subquery/Subquerable.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; + +namespace SqlSugar +{ + /// + /// 开发中.... + /// + /// + public class Subqueryable where T : class, new() + { + public Subqueryable Where(Func expression) + { + return this; + } + + public TResult Select(Func expression) where TResult :struct + { + return default(TResult); + } + public string Select(Func expression) + { + return default(string); + } + + public TResult Max(Func expression) where TResult : struct + { + return default(TResult); + } + + public TResult Min(Func expression) where TResult : struct + { + return default(TResult); + } + public string Max(Func expression) + { + return default(string); + } + public string Min(Func expression) + { + return default(string); + } + + public bool Any() + { + return default(bool); + } + + public bool NotAny() + { + return default(bool); + } + + public int Count() + { + return default(int); + } + } +} diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/DependencyManagement.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/DependencyManagement.cs new file mode 100644 index 000000000..43a53d6c8 --- /dev/null +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/DependencyManagement.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Data.SqlClient; +using System.Linq; +using System.Reflection; +using System.Text; +namespace SqlSugar +{ + internal class DependencyManagement + { + private static bool IsTryJsonNet = false; + private static bool IsTryMySqlData = false; + private static bool IsTrySqlite = false; + public static void TryJsonNet() + { + if (!IsTryJsonNet) + { + try + { + JsonHelper.SerializeObject(new { }); + IsTryJsonNet = true; + } + catch + { + var message = ErrorMessage.GetThrowMessage( + " SqlSugar Some functions are used in newtonsoft ,Nuget references Newtonsoft.Json 9.0.0.1 + .", + " SqlSugar 部分功能用到Newtonsoft.Json.dll,需要在Nuget上安装 Newtonsoft.Json 9.0.0.1及以上版本,如果有版本兼容问题请先删除原有引用"); + throw new Exception(message); + } + } + } + public static void TryMySqlData() + { + if (!IsTryMySqlData) + { + try + { + MySqlProvider db = new MySqlProvider(); + var conn = db.GetAdapter(); + IsTryMySqlData = true; + } + catch + { + var message = ErrorMessage.GetThrowMessage( + "You need to refer to MySql.Data.dll" , + "需要引用MySql.Data.dll,请在Nuget安装最新稳定版本,如果有版本兼容问题请先删除原有引用"); + throw new Exception(message); + } + } + } + + public static void TrySqlite() + { + if (!IsTrySqlite) + { + try + { + SqliteProvider db = new SqliteProvider(); + var conn= db.GetAdapter(); + IsTrySqlite = true; + } + catch(Exception ex) + { + var message = ErrorMessage.GetThrowMessage( + "You need to refer to Microsoft.Data.Sqlite." + ex.Message, + "你需要引用System.Data.SQLite.dll,如果有版本兼容问题请先删除原有引用"); + throw new Exception(message); + } + } + } + } +} diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/InstanceFactory.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/InstanceFactory.cs index db3d42196..5bf962ab6 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/InstanceFactory.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/InstanceFactory.cs @@ -281,7 +281,7 @@ namespace SqlSugar var result = (Restult)Activator.CreateInstance(type, true); return result; } - private static T CreateInstance(string className) + public static T CreateInstance(string className) { Type type; if (typeCache.ContainsKey(className)) diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/RewritableMethods.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/RewritableMethods.cs index bb3d6b2e7..9df038461 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/RewritableMethods.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/RewritableMethods.cs @@ -6,7 +6,6 @@ using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; -using Newtonsoft.Json; namespace SqlSugar { public class RewritableMethods : IRewritableMethods @@ -191,9 +190,12 @@ namespace SqlSugar /// public string SerializeObject(object value) { - return JsonConvert.SerializeObject(value); + DependencyManagement.TryJsonNet(); + return JsonHelper.SerializeObject(value); } + + /// /// Serialize Object /// @@ -201,8 +203,8 @@ namespace SqlSugar /// public T DeserializeObject(string value) { - var jSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; - return JsonConvert.DeserializeObject(value, jSetting); + DependencyManagement.TryJsonNet(); + return JsonHelper.DeserializeObject(value); } #endregion @@ -255,7 +257,7 @@ namespace SqlSugar } deserializeObject.Add(childRow); } - return JsonConvert.DeserializeObject(JsonConvert.SerializeObject(deserializeObject)); + return this.DeserializeObject(this.SerializeObject(deserializeObject)); } #endregion diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/ILambdaExpressions.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/ILambdaExpressions.cs index ae05d433d..6d390cd5b 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/ILambdaExpressions.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/ILambdaExpressions.cs @@ -21,6 +21,8 @@ namespace SqlSugar List Parameters { get; set; } ExpressionResult Result { get; set; } string SqlParameterKeyWord { get; } + string SingleTableNameSubqueryShortName { get; set; } + string GetAsString(string fieldName, string fieldValue); void Resolve(Expression expression, ResolveExpressType resolveType); void Clear(); diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugarClient.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugarClient.cs index 3cd74d59e..d039201cd 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugarClient.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugarClient.cs @@ -16,15 +16,27 @@ namespace SqlSugar /// public partial class SqlSugarClient : SqlSugarAccessory, IDisposable { - + #region Constructor public SqlSugarClient(ConnectionConfig config) { base.Context = this; base.CurrentConnectionConfig = config; - if (config.DbType == DbType.Oracle) + Check.ArgumentNullException(config, "config is null"); + switch (config.DbType) { - throw new Exception("Oracle developed 60%,to be continued "); + case DbType.MySql: + DependencyManagement.TryMySqlData(); + break; + case DbType.SqlServer: + break; + case DbType.Sqlite: + DependencyManagement.TrySqlite(); + break; + case DbType.Oracle: + throw new Exception("Oracle developed 60%,to be continued"); + default: + throw new Exception("ConnectionConfig.DbType is null"); } } #endregion diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/ErrorMessage.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/ErrorMessage.cs index 4e6e9ed67..4e5c4eace 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/ErrorMessage.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/ErrorMessage.cs @@ -71,7 +71,8 @@ namespace SqlSugar { List formatArgs = new List() { enMessage, cnMessage }; formatArgs.AddRange(args); - return string.Format("\r\n English Message : {0}\r\n Chinese Message : {1}", formatArgs.ToArray()); + return string.Format(@"English Message : {0} +Chinese Message : {1}", formatArgs.ToArray()); } } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/JsonHelper.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/JsonHelper.cs new file mode 100644 index 000000000..5a2b45b4c --- /dev/null +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/JsonHelper.cs @@ -0,0 +1,22 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace SqlSugar +{ + internal class JsonHelper + { + public static string SerializeObject(object value) + { + return JsonConvert.SerializeObject(value); + } + + public static T DeserializeObject(string value) + { + var jSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; + return JsonConvert.DeserializeObject(value, jSetting); + } + } +} diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/UtilConstants.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/UtilConstants.cs index f89b173d9..224e05f84 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/UtilConstants.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Utilities/UtilConstants.cs @@ -9,6 +9,7 @@ namespace SqlSugar public const string Dot = "."; public const char DotChar = '.'; internal const string Space = " "; + internal const char SpaceChar =' '; internal const string AssemblyName = "SqlSugar"; internal const string ReplaceKey = "{662E689B-17A1-4D06-9D27-F29EAB8BC3D6}";