diff --git a/Src/Asp.Net/SqlServerTest/UnitTest/ExpressionTest/Method.cs b/Src/Asp.Net/SqlServerTest/UnitTest/ExpressionTest/Method.cs index 804dd8f30..c0a3c1ed3 100644 --- a/Src/Asp.Net/SqlServerTest/UnitTest/ExpressionTest/Method.cs +++ b/Src/Asp.Net/SqlServerTest/UnitTest/ExpressionTest/Method.cs @@ -33,6 +33,8 @@ namespace OrmTest.UnitTest MappingColumn(); IIF(); IIF2(); + IIF3(); + IIF4(); #region StringIsNullOrEmpty HasValue(); HasNumber(); @@ -704,6 +706,38 @@ namespace OrmTest.UnitTest new SugarParameter("@Const3",1) }, "IIF2 error"); } + + private void IIF3() + { + Expression> exp = it => SqlFunc.IIF(SqlFunc.Contains(it.Name, "a"), true, false) == true; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(( CASE WHEN ([Name] like '%'+@MethodConst0+'%') THEN @MethodConst1 ELSE @MethodConst2 END ) = @Const3 )", new List() + { + new SugarParameter("@MethodConst0","a"), + new SugarParameter("@MethodConst1",true), + new SugarParameter("@MethodConst2",false), + new SugarParameter("@Const3",true) + }, "IIF3 error"); + } + + private void IIF4() + { + //Expression> exp = it => SqlFunc.IIF(true, it.Bool1, it.Bool2) == true; + //SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + //expContext.Resolve(exp, ResolveExpressType.WhereSingle); + //var value = expContext.Result.GetString(); + //var pars = expContext.Parameters; + //base.Check(value, pars, "(( CASE WHEN ([Name] like '%'+@MethodConst0+'%') THEN @MethodConst1 ELSE @MethodConst2 END ) = @Const3 )", new List() + //{ + // new SugarParameter("@MethodConst0","a"), + // new SugarParameter("@MethodConst1",true), + // new SugarParameter("@MethodConst2",false), + // new SugarParameter("@Const3",true) + //}, "IIF4 error"); + } } } diff --git a/Src/Asp.Net/SqlSugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs b/Src/Asp.Net/SqlSugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs index 028f39184..6cb65eac0 100644 --- a/Src/Asp.Net/SqlSugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs +++ b/Src/Asp.Net/SqlSugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs @@ -21,7 +21,7 @@ namespace SqlSugar appendArgs = new List(); var dateType = MethodTimeMapping[methodName]; string paramterName = this.Context.SqlParameterKeyWord + ExpressionConst.Const + this.Context.ParameterIndex; - appendArgs.Add(new MethodCallExpressionArgs() { IsMember=false, MemberName= paramterName, MemberValue=dateType }); + appendArgs.Add(new MethodCallExpressionArgs() { IsMember = false, MemberName = paramterName, MemberValue = dateType }); this.Context.Parameters.Add(new SugarParameter(paramterName, dateType.ToString())); this.Context.ParameterIndex++; methodName = "DateAdd"; @@ -47,7 +47,7 @@ namespace SqlSugar } if (isValidNativeMethod) { - NativeExtensionMethod(parameter, express, isLeft, MethodMapping[methodName],appendArgs); + NativeExtensionMethod(parameter, express, isLeft, MethodMapping[methodName], appendArgs); } else { @@ -81,7 +81,6 @@ namespace SqlSugar break; } } - private void NativeExtensionMethod(ExpressionParameter parameter, MethodCallExpression express, bool? isLeft, string name, List appendArgs = null) { var method = express.Method; @@ -115,21 +114,13 @@ namespace SqlSugar if (name == "GetSelfAndAutoFill") { var memberValue = (args.First() as MemberExpression).Expression.ToString(); - model.Args.Add(new MethodCallExpressionArgs() { MemberValue= memberValue, IsMember=true, MemberName= memberValue }); + model.Args.Add(new MethodCallExpressionArgs() { MemberValue = memberValue, IsMember = true, MemberName = memberValue }); } else { foreach (var item in args) { - var isBinaryExpression = item is BinaryExpression || item is MethodCallExpression; - if (isBinaryExpression) - { - model.Args.Add(GetMethodCallArgs(parameter, item)); - } - else - { - Default(parameter, model, item); - } + AppendItem(parameter, name, args, model, item); } if (appendArgs != null) { @@ -142,15 +133,7 @@ namespace SqlSugar { foreach (var item in args) { - var isBinaryExpression = item is BinaryExpression || item is MethodCallExpression; - if (isBinaryExpression) - { - model.Args.Add(GetMethodCallArgs(parameter, item)); - } - else - { - Default(parameter, model, item); - } + AppendItem(parameter, name, args, model, item); } if (appendArgs != null) { @@ -159,7 +142,105 @@ namespace SqlSugar var methodValue = GetMdthodValue(name, model); base.AppendValue(parameter, isLeft, methodValue); } - private void Default(ExpressionParameter parameter, MethodCallExpressionModel model, Expression item) + + private void AppendItem(ExpressionParameter parameter, string name, IEnumerable args, MethodCallExpressionModel model, Expression item) + { + var isBinaryExpression = item is BinaryExpression || item is MethodCallExpression; + var isIFFBoolMember = name == "IIF" && (args.Last() is MemberExpression) && (args.Last() as MemberExpression).Type == PubConst.BoolType; + var isIFFUnary = name == "IIF" && (args.Last() is UnaryExpression) && (args.Last() as UnaryExpression).Operand.Type == PubConst.BoolType; + var isIFFBoolBinary = name == "IIF" && (args.Last() is BinaryExpression) && (args.Last() as BinaryExpression).Type == PubConst.BoolType; + if (isIFFUnary && item != args.First()) + { + AppendModelByIIFMember(parameter, model, (item as UnaryExpression).Operand); + } + else if (isIFFBoolMember && item != args.First()) + { + AppendModelByIIFMember(parameter, model, item); + + } + else if (isIFFBoolBinary && item != args.First()) + { + AppendModelByIIFBinary(parameter, model, item); + + } + else if (isBinaryExpression) + { + model.Args.Add(GetMethodCallArgs(parameter, item)); + } + else + { + AppendModel(parameter, model, item); + } + } + private void AppendModelByIIFMember(ExpressionParameter parameter, MethodCallExpressionModel model, Expression item) + { + parameter.CommonTempData = CommonTempDataType.Result; + base.Expression = item; + base.Start(); + var methodCallExpressionArgs = new MethodCallExpressionArgs() + { + IsMember = parameter.ChildExpression is MemberExpression, + MemberName = parameter.CommonTempData + }; + if (methodCallExpressionArgs.IsMember && parameter.ChildExpression != null && parameter.ChildExpression.ToString() == "DateTime.Now") + { + methodCallExpressionArgs.IsMember = false; + } + var value = methodCallExpressionArgs.MemberName; + if (methodCallExpressionArgs.IsMember) + { + var childExpression = parameter.ChildExpression as MemberExpression; + if (childExpression.Expression != null && childExpression.Expression is ConstantExpression) + { + methodCallExpressionArgs.IsMember = false; + } + } + if (methodCallExpressionArgs.IsMember == false) + { + var parameterName = this.Context.SqlParameterKeyWord + ExpressionConst.MethodConst + this.Context.ParameterIndex; + this.Context.ParameterIndex++; + methodCallExpressionArgs.MemberName = parameterName; + methodCallExpressionArgs.MemberValue = value; + this.Context.Parameters.Add(new SugarParameter(parameterName, value)); + } + model.Args.Add(methodCallExpressionArgs); + parameter.ChildExpression = null; + } + private void AppendModelByIIFBinary(ExpressionParameter parameter, MethodCallExpressionModel model, Expression item) + { + parameter.CommonTempData = CommonTempDataType.Result; + base.Expression = item; + base.Start(); + var methodCallExpressionArgs = new MethodCallExpressionArgs() + { + IsMember = parameter.ChildExpression is MemberExpression, + MemberName = parameter.CommonTempData + }; + if (methodCallExpressionArgs.IsMember && parameter.ChildExpression != null && parameter.ChildExpression.ToString() == "DateTime.Now") + { + methodCallExpressionArgs.IsMember = false; + } + var value = methodCallExpressionArgs.MemberName; + if (methodCallExpressionArgs.IsMember) + { + var childExpression = parameter.ChildExpression as MemberExpression; + if (childExpression.Expression != null && childExpression.Expression is ConstantExpression) + { + methodCallExpressionArgs.IsMember = false; + } + } + if (methodCallExpressionArgs.IsMember == false) + { + var parameterName = this.Context.SqlParameterKeyWord + ExpressionConst.MethodConst + this.Context.ParameterIndex; + this.Context.ParameterIndex++; + methodCallExpressionArgs.MemberName = parameterName; + methodCallExpressionArgs.MemberValue = value; + this.Context.Parameters.Add(new SugarParameter(parameterName, value)); + } + model.Args.Add(methodCallExpressionArgs); + parameter.ChildExpression = null; + } + private void AppendModel(ExpressionParameter parameter, MethodCallExpressionModel model, Expression item) { parameter.CommonTempData = CommonTempDataType.Result; base.Expression = item; @@ -225,7 +306,7 @@ namespace SqlSugar return this.Context.DbMehtods.DateIsSameDay(model); else { - var dsResult=this.Context.DbMehtods.DateIsSameByType(model); + var dsResult = this.Context.DbMehtods.DateIsSameByType(model); this.Context.Parameters.RemoveAll(it => it.ParameterName == model.Args[2].MemberName.ObjToString()); return dsResult; } @@ -234,12 +315,12 @@ namespace SqlSugar return this.Context.DbMehtods.DateAddDay(model); else { - var daResult=this.Context.DbMehtods.DateAddByType(model); + var daResult = this.Context.DbMehtods.DateAddByType(model); this.Context.Parameters.RemoveAll(it => it.ParameterName == model.Args[2].MemberName.ObjToString()); return daResult; } case "DateValue": - var dvResult= this.Context.DbMehtods.DateValue(model); + var dvResult = this.Context.DbMehtods.DateValue(model); this.Context.Parameters.RemoveAll(it => it.ParameterName == model.Args[1].MemberName.ObjToString()); return dvResult; case "Between": @@ -290,7 +371,7 @@ namespace SqlSugar return mappingColumnResult; case "GetSelfAndAutoFill": this.Context.Parameters.RemoveAll(it => it.ParameterName == model.Args[0].MemberName.ObjToString()); - return this.Context.DbMehtods.GetSelfAndAutoFill(model.Args[0].MemberValue.ObjToString(),this.Context.IsSingle); + return this.Context.DbMehtods.GetSelfAndAutoFill(model.Args[0].MemberValue.ObjToString(), this.Context.IsSingle); default: break; }