using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace SqlSugar { /// ///MethodCall Helper /// public partial class MethodCallExpressionResolve : BaseResolve { private void CusMethod(ExpressionParameter parameter, MethodCallExpression express, bool? isLeft) { try { OneToManyNavgateExpression nav = new OneToManyNavgateExpression(this.Context?.SugarContext?.Context, this); nav.ParameterIndex = this.Context.ParameterIndex; this.Context.ParameterIndex++; if (nav.IsNavgate(express)) { var sql = nav.GetSql(); SetNavigateResult(); this.Context.SingleTableNameSubqueryShortName = nav.ShorName; base.AppendValue(parameter, isLeft, sql); return; } OneToManyNavgateExpressionN nav2 = new OneToManyNavgateExpressionN(this.Context?.SugarContext?.Context, this); if (nav2.IsNavgate(express)) { var sql = nav2.GetSql(); SetNavigateResult(); this.Context.SingleTableNameSubqueryShortName = nav2.shorName; base.AppendValue(parameter, isLeft, sql); return; } var constValue = ExpressionTool.DynamicInvoke(express); if (constValue is MapperSql) { constValue = (constValue as MapperSql).Sql; base.AppendValue(parameter, isLeft, constValue); return; } parameter.BaseParameter.CommonTempData = constValue; var parameterName = base.AppendParameter(constValue); if (parameter.BaseParameter.CommonTempData != null && parameter.BaseParameter.CommonTempData.Equals(CommonTempDataType.Result)) { this.Context.Result.Append(parameterName); } else { base.AppendValue(parameter, isLeft, parameterName); } } catch (Exception ex) { if (ex is SqlSugarException) { Check.Exception(true, string.Format(ex.Message, express.Method.Name)); } else { Check.Exception(true, string.Format(ErrorMessage.MethodError, express.Method.Name)); } } } private static bool MethodValueIsTrue(object methodValue) { return methodValue != null && methodValue.ToString().Contains("THEN true ELSE false END"); } private object packIfElse(object methodValue) { methodValue = this.Context.DbMehtods.CaseWhen(new List>() { new KeyValuePair("IF",methodValue.ObjToString()), new KeyValuePair("Return", this.Context.DbMehtods.TrueValue()), new KeyValuePair("End", this.Context.DbMehtods.FalseValue()) }); return methodValue; } private void SetShortName(Expression exp) { var lamExp = (exp as LambdaExpression); if (lamExp.Parameters != null && lamExp.Parameters.Count == 1) { if (this.Context.SingleTableNameSubqueryShortName == null) { this.Context.SingleTableNameSubqueryShortName = lamExp.Parameters.First().Name; } } } private void AppendItem(ExpressionParameter parameter, string name, IEnumerable args, MethodCallExpressionModel model, Expression item) { if (ExpressionTool.IsUnConvertExpress(item)) { item = (item as UnaryExpression).Operand; } if (this.Context.IsSingle && args.Any(it => ExpressionTool.IsSubQuery(it)) && base.BaseParameter?.BaseParameter?.BaseParameter?.CurrentExpression != null) { var exp = base.BaseParameter?.BaseParameter?.BaseParameter?.CurrentExpression; if (exp is LambdaExpression) { SetShortName(exp); } else if (exp is UnaryExpression) { exp = base.BaseParameter?.BaseParameter?.BaseParameter?.BaseParameter?.CurrentExpression; if (exp is LambdaExpression) { SetShortName(exp); } } } else if (this.Context.IsSingle && args.Any(it => ExpressionTool.IsIsNullSubQuery(it))) { var exp = base.BaseParameter?.BaseParameter?.BaseParameter?.CurrentExpression; if (exp is LambdaExpression) { SetShortName(exp); } else if (exp is UnaryExpression) { exp = base.BaseParameter?.BaseParameter?.BaseParameter?.BaseParameter?.CurrentExpression; if (exp is LambdaExpression) { SetShortName(exp); } } } var isBinaryExpression = item is BinaryExpression || item is MethodCallExpression; var isConst = item is ConstantExpression; var isIIF = name == "IIF"; var isSubIIF = (isIIF && item.ToString().StartsWith("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; var isIFFBoolMethod = isIIF && (item is MethodCallExpression) && (item as MethodCallExpression).Type == UtilConstants.BoolType; var isFirst = item == args.First(); var isBoolValue = item.Type == UtilConstants.BoolType && item.ToString().StartsWith("value("); var isLength =ExpressionTool.GetIsLength(item); if (isFirst && isIIF && isConst) { var value = (item as ConstantExpression).Value.ObjToBool() ? this.Context.DbMehtods.True() : this.Context.DbMehtods.False(); var methodCallExpressionArgs = new MethodCallExpressionArgs() { IsMember = true, MemberName = value, MemberValue = value }; model.Args.Add(methodCallExpressionArgs); } else if (isFirst && isIIF && isIFFBoolMember && (item as MemberExpression)?.Member?.Name == "HasValue") { var value = base.GetNewExpressionValue(item); var methodCallExpressionArgs = new MethodCallExpressionArgs() { IsMember = true, MemberName = value, MemberValue = value }; model.Args.Add(methodCallExpressionArgs); } else if (name != null && name != "MappingColumn" && !name.StartsWith("Row") && ExpressionTool.GetMethodName(item) == "Format" && ExpressionTool.GetParameters(item).Count == 0) { var value = ExpressionTool.DynamicInvoke(item); var p = AppendParameter(value); var methodCallExpressionArgs = new MethodCallExpressionArgs() { IsMember = true, MemberName = p, MemberValue = p }; model.Args.Add(methodCallExpressionArgs); } else if (isLength) { var value = GetNewExpressionValue(item); var methodCallExpressionArgs = new MethodCallExpressionArgs() { IsMember = true, MemberName = value, MemberValue = value }; model.Args.Add(methodCallExpressionArgs); } else if (isIFFUnary && !isFirst) { AppendModelByIIFMember(parameter, model, (item as UnaryExpression).Operand); } else if (isIFFBoolMember && !isFirst) { AppendModelByIIFMember(parameter, model, item); } else if (isIFFBoolBinary && !isFirst) { var binaryExp = item as BinaryExpression; var binaryExpEqual = binaryExp != null && ExpressionTool.IsComparisonOperatorBool(binaryExp); if (binaryExpEqual) { var expValue = GetNewExpressionValue(item); expValue = this.Context.DbMehtods.IIF(new MethodCallExpressionModel() { Name = "IIF", Args = new List() { new MethodCallExpressionArgs(){ IsMember=true, MemberName=expValue }, new MethodCallExpressionArgs(){ IsMember=true, MemberName= Context.DbMehtods.TrueValue() }, new MethodCallExpressionArgs(){ IsMember=true, MemberName= Context.DbMehtods.FalseValue() } } }); model.Args.Add(new MethodCallExpressionArgs() { IsMember = false, MemberName = expValue, MemberValue = expValue }); } else { AppendModelByIIFBinary(parameter, model, item); } } else if (isIFFBoolMethod && !isFirst) { AppendModelByIIFMethod(parameter, model, item); } else if (isBinaryExpression) { model.Args.Add(GetMethodCallArgs(parameter, item, name)); } else if (isSubIIF) { model.Args.Add(GetMethodCallArgs(parameter, item)); } else if (isBoolValue && !isIIF && item is MemberExpression) { model.Args.Add(GetMethodCallArgs(parameter, (item as MemberExpression).Expression)); } else if (isBoolValue && isIIF && item is MemberExpression&&ExpressionTool.GetParameters(item).Count()==0) { var expValue = AppendParameter(ExpressionTool.DynamicInvoke(item)); expValue = this.Context.DbMehtods.Equals(new MethodCallExpressionModel() { Name = "Equals", Args = new List() { new MethodCallExpressionArgs(){ IsMember=true, MemberName=expValue }, new MethodCallExpressionArgs(){ IsMember=true, MemberName= Context.DbMehtods.TrueValue() } } }); model.Args.Add(new MethodCallExpressionArgs() { IsMember = false, MemberName = expValue, MemberValue = expValue }); } else if (isBoolValue && isIIF && item is MemberExpression) { var argItem = GetMethodCallArgs(parameter, (item as MemberExpression).Expression); if (argItem.IsMember) { var pName = this.Context.SqlParameterKeyWord + "true_0"; if (!this.Context.Parameters.Any(it => it.ParameterName == pName)) this.Context.Parameters.Add(new SugarParameter(pName, true)); argItem.MemberName = $" {argItem.MemberName}={pName} "; } model.Args.Add(argItem); } else if (name.IsIn("ListAny", "ListAll") && item is LambdaExpression) { var sql = GetNewExpressionValue(item, ResolveExpressType.WhereMultiple); var lamExp = (item as LambdaExpression); var pExp = lamExp.Parameters[0]; var pname = pExp.Name; model.Args.Add(new MethodCallExpressionArgs() { MemberValue = new ListAnyParameter() { Sql = sql, Name = pname, Columns = this.Context.SugarContext.Context.EntityMaintenance.GetEntityInfo(pExp.Type).Columns, ConvetColumnFunc = this.Context.GetTranslationColumnName } }); if (this.Context.IsSingle && this.Context.SingleTableNameSubqueryShortName == null) { ParameterExpressionVisitor visitor = new ParameterExpressionVisitor(); visitor.Visit(lamExp); var tableParamter = visitor.Parameters.FirstOrDefault(it => it.Name != pname); if (tableParamter != null) { this.Context.SingleTableNameSubqueryShortName = tableParamter.Name; } } } else { AppendModel(parameter, model, item, name, args); } } 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) { Check.Exception(true, "The SqlFunc.IIF(arg1,arg2,arg3) , {0} argument do not support ", item.ToString()); } private void AppendModelByIIFMethod(ExpressionParameter parameter, MethodCallExpressionModel model, Expression item) { var methodExpression = item as MethodCallExpression; if (methodExpression.Method.Name.IsIn("ToBool", "ToBoolean", "IIF")) { model.Args.Add(base.GetMethodCallArgs(parameter, item)); } else if (methodExpression.Method.Name.IsIn("Contains", "EndsWith", "StartsWith")) { Expression conditionalExpression =ExpressionTool.GetConditionalExpression(item); model.Args.Add(base.GetMethodCallArgs(parameter, conditionalExpression)); } else { Check.Exception(true, "The SqlFunc.IIF(arg1,arg2,arg3) , {0} argument do not support ", item.ToString()); } } private void AppendModel(ExpressionParameter parameter, MethodCallExpressionModel model, Expression item,string name, IEnumerable args) { parameter.CommonTempData = CommonTempDataType.Result; base.Expression = item; var isRemoveParamter = false; var isNegate = false; if (item.Type == UtilConstants.DateType && parameter.CommonTempData.ObjToString() == CommonTempDataType.Result.ToString() && item.ToString() == "DateTime.Now.Date") { parameter.CommonTempData = DateTime.Now.Date; } else if (item is ConditionalExpression) { parameter.CommonTempData = GetNewExpressionValue(item); } else if (IsNot(item)) { parameter.CommonTempData = GetNewExpressionValue(item); } else if (IsDateDate(item)) { parameter.CommonTempData = GetNewExpressionValue(item); } else if (IsDateValue(item)) { parameter.CommonTempData = GetNewExpressionValue(item); } else if (model.Name == "ToString" && item is ConstantExpression && (item as ConstantExpression).Type.IsEnum()) { parameter.CommonTempData = item.ToString(); } else if (IsDateItemValue(item)) { parameter.CommonTempData = GetNewExpressionValue(item); } else if (name == "Format" && item is NewArrayExpression) { var exps = (item as NewArrayExpression).Expressions; parameter.CommonTempData = exps.Select(it => { var res = GetNewExpressionValue(ExpressionTool.RemoveConvert(it)); return res; }).ToArray(); } else if (name == "Format" && item is ConstantExpression) { parameter.CommonTempData = ExpressionTool.GetExpressionValue(item); } else if (name == "FullTextContains" && item is NewArrayExpression) { var array = ExpressionTool.GetNewArrayMembers(item as NewArrayExpression); parameter.CommonTempData = array.Select(it=>this.Context.GetTranslationColumnName(it)).ToList(); isRemoveParamter = true; } else if (ExpressionTool.IsNegate(item) && (item as UnaryExpression)?.Operand is MemberExpression) { var exp = (item as UnaryExpression)?.Operand; parameter.CommonTempData = GetNewExpressionValue(exp) + " * -1 "; isRemoveParamter = true; isNegate = true; } else { base.Start(); } var methodCallExpressionArgs = new MethodCallExpressionArgs() { IsMember = parameter.ChildExpression is MemberExpression && !ExpressionTool.IsConstExpression(parameter.ChildExpression as MemberExpression), MemberName = parameter.CommonTempData }; if (this.Context?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.IsCorrectErrorSqlParameterName == true) { if (methodCallExpressionArgs.MemberName is string) { methodCallExpressionArgs.MemberName = ExpressionTool.ResolveMemberValue(this.Context, item, methodCallExpressionArgs.MemberName?.ToString()); } } if (methodCallExpressionArgs.MemberName is MapperSql) { methodCallExpressionArgs.MemberName = (methodCallExpressionArgs.MemberName as MapperSql).Sql; } 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 (IsDateDate(item) || IsDateValue(item) || IsDateItemValue(item) || item is ConditionalExpression || IsNot(item)) { methodCallExpressionArgs.IsMember = true; } if (methodCallExpressionArgs.IsMember == false && (item is MethodCallExpression && item.ToString() == "GetDate()") || (item is UnaryExpression && ((UnaryExpression)item).Operand.ToString() == "GetDate()")) { var parameterName = this.Context.SqlParameterKeyWord + ExpressionConst.MethodConst + this.Context.ParameterIndex; this.Context.ParameterIndex++; methodCallExpressionArgs.MemberName = value; methodCallExpressionArgs.MemberValue = null; } else if (methodCallExpressionArgs.IsMember == false&&isNegate==false) { var parameterName = this.Context.SqlParameterKeyWord + ExpressionConst.MethodConst + this.Context.ParameterIndex; this.Context.ParameterIndex++; methodCallExpressionArgs.MemberName = parameterName; if (name == "ToString"&&UtilMethods.GetUnderType(base.Expression.Type).IsEnum()) { value = value?.ToString(); } else if (name == "ContainsArray"&&args.Count()==2&& value!= null && value is IList) { List result = new List(); foreach (var memItem in (value as IList)) { result.Add(GetMemberValue(memItem, args.Last())); } value = result; } else if (!(item is ParameterExpression)&& name.IsIn("Contains", "StartsWith", "EndsWith") &&item==args.Last()&& ExpressionTool.IsSqlParameterDbType(this.Context, args.First())) { var myvalue = ExpressionTool.DynamicInvoke(args.Last()); var parametre = ExpressionTool.GetParameterBySqlParameterDbType(this.Context.ParameterIndex,myvalue, this.Context, args.First()); this.Context.Parameters.Add(parametre); methodCallExpressionArgs.MemberName = parametre.ParameterName; methodCallExpressionArgs.MemberValue = parametre.Value; methodCallExpressionArgs.IsMember = true; isRemoveParamter = true; this.Context.ParameterIndex++; } methodCallExpressionArgs.MemberValue = value; if (isRemoveParamter != true) { if (value == null && item != null) { this.Context.Parameters.Add(new SugarParameter(parameterName, value, UtilMethods.GetUnderType(item.Type))); } else { this.Context.Parameters.Add(new SugarParameter(parameterName, value)); } } } model.Args.Add(methodCallExpressionArgs); parameter.ChildExpression = null; } private void GetConfigValue(MethodCallExpression express, ExpressionParameter parameter) { var exp = express.Arguments[0]; var name = Regex.Match(express.Method.ToString(), @"GetConfigValue\[(.+)\]").Groups[1].Value; string code = null; if (express.Arguments.Count > 1) { code = ExpressionTool.GetExpressionValue(express.Arguments[1]) + ""; } var entityDb = SqlFuncExtendsion.TableInfos.FirstOrDefault(y => y.Type.Name == name && y.Code == code); Check.Exception(entityDb == null, string.Format("GetConfigValue no configuration Entity={0} UniqueCode={1}", name, code)); var entity = new ConfigTableInfo() { Code = entityDb.Code, TableName = entityDb.TableName, Key = entityDb.Key, Parameter = new List(), Type = entityDb.Type, Value = entityDb.Value, Where = entityDb.Where }; if (entityDb.Parameter != null && entityDb.Parameter.Any()) { foreach (var item in entityDb.Parameter) { entity.Parameter.Add(new SugarParameter("", null) { DbType = item.DbType, Direction = item.Direction, IsArray = item.IsArray, IsJson = item.IsJson, IsNullable = item.IsNullable, IsRefCursor = item.IsRefCursor, ParameterName = item.ParameterName, Size = item.Size, SourceColumn = item.SourceColumn, SourceColumnNullMapping = item.SourceColumnNullMapping, SourceVersion = item.SourceVersion, TempDate = item.TempDate, TypeName = item.TypeName, Value = item.Value, _Size = item._Size }); } } string sql = " (SELECT {0} FROM {1} WHERE {2}={3}"; if (ExpressionTool.IsUnConvertExpress(exp)) { exp = (exp as UnaryExpression).Operand; } var member = exp as MemberExpression; var it = member.Expression; var type = it.Type; var properyName = member.Member.Name; var eqName = string.Format("{0}.{1}", this.Context.GetTranslationColumnName(it.ToString()), this.Context.GetDbColumnName(type.Name, properyName)); if (this.Context.IsSingle) { this.Context.SingleTableNameSubqueryShortName = it.ToString(); } sql = string.Format(sql, entity.Value, this.Context.GetTranslationColumnName(entity.TableName), entity.Key, eqName); if (entity.Parameter != null) { foreach (var item in entity.Parameter) { var oldName = item.ParameterName; item.ParameterName = Regex.Split(oldName, "_con_").First() + "_con_" + this.Context.ParameterIndex; entity.Where = entity.Where.Replace(oldName, item.ParameterName); } this.Context.ParameterIndex++; this.Context.Parameters.AddRange(entity.Parameter); } if (entity.Where.HasValue()) { sql += " AND " + entity.Where; } sql += " )"; if (this.Context.ResolveType.IsIn(ResolveExpressType.SelectMultiple, ResolveExpressType.SelectSingle, ResolveExpressType.Update)) { parameter.BaseParameter.CommonTempData = sql; } else { AppendMember(parameter, parameter.IsLeft, sql); } } private object GetMethodValue(string name, MethodCallExpressionModel model) { model.Parameters = this.Context.Parameters; if (IsExtMethod(name)) { model.Expression = this.Expression; model.BaseExpression = this.BaseParameter.CurrentExpression; DbType type = DbType.SqlServer; if (this.Context is SqlServerExpressionContext) type = DbType.SqlServer; else if (this.Context is MySqlExpressionContext) type = DbType.MySql; else if (this.Context is SqliteExpressionContext) type = DbType.Sqlite; else if (this.Context is OracleExpressionContext) type = DbType.Oracle; else if (this.Context is PostgreSQLExpressionContext) type = DbType.PostgreSQL; else if (this.Context.GetType().Name.StartsWith("MySql")) { type = DbType.MySql; } else { type = GetType(this.Context.GetType().Name); } return this.Context.SqlFuncServices.First(it => it.UniqueMethodName == name).MethodValue(model, type, this.Context); } else { var iLike = this.Context?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.EnableILike == true; if (name == "Parse" && TempParseType.IsIn(UtilConstants.GuidType) && model.Args != null && model.Args.Count() > 1) { name = "Equals"; } else if (name == "Parse") { name = "To" + TempParseType.Name; } else if (name == "IsNullOrWhiteSpace") { name = "IsNullOrEmpty"; } if (model.Conext == null) { model.Conext = this.Context; } switch (name) { case "IIF": return this.Context.DbMehtods.IIF(model); case "HasNumber": return this.Context.DbMehtods.HasNumber(model); case "HasValue": return this.Context.DbMehtods.HasValue(model); case "IsNullOrEmpty": model.Conext = this.Context; return this.Context.DbMehtods.IsNullOrEmpty(model); case "ToLower": return this.Context.DbMehtods.ToLower(model); case "ToUpper": return this.Context.DbMehtods.ToUpper(model); case "Trim": return this.Context.DbMehtods.Trim(model); case "Contains": return GetLike(this.Context.DbMehtods.Contains(model),iLike); case "ContainsArray": if (model.Args[0].MemberValue == null) { var first = this.Context.Parameters.FirstOrDefault(it => it.ParameterName == model.Args[0].MemberName.ObjToString()); if (first.HasValue()) { model.Args[0].MemberValue = first.Value; } } if (this.Context.TableEnumIsString == true) { List enumStringList = new List(); foreach (var inItem in (model.Args[0].MemberValue as IEnumerable)) { if (inItem != null) { if (UtilMethods.GetUnderType(inItem.GetType()).IsEnum()) { enumStringList.Add(inItem.ToString()); } } } if (enumStringList.Any()) { model.Args[0].MemberValue = enumStringList; } } var caResult = this.Context.DbMehtods.ContainsArray(model); this.Context.Parameters.RemoveAll(it => it.ParameterName == model.Args[0].MemberName.ObjToString()); return caResult; case "ContainsArrayUseSqlParameters": if (model.Args[0].MemberValue == null) { var first = this.Context.Parameters.FirstOrDefault(it => it.ParameterName == model.Args[0].MemberName.ObjToString()); if (first.HasValue()) { model.Args[0].MemberValue = first.Value; } } model.Data = this.Context.SqlParameterKeyWord + "INP_" + this.Context.ParameterIndex; this.Context.ParameterIndex++; if (model.Args[0].MemberValue.HasValue()) { var inValueIEnumerable = (IEnumerable)model.Args[0].MemberValue; int i = 0; foreach (var item in inValueIEnumerable) { this.Context.Parameters.Add(new SugarParameter(model.Data + "_" + i, item)); i++; } } var caResult2 = this.Context.DbMehtods.ContainsArrayUseSqlParameters(model); this.Context.Parameters.RemoveAll(it => it.ParameterName == model.Args[0].MemberName.ObjToString()); return caResult2; case "Equals": return this.Context.DbMehtods.Equals(model); case "EqualsNull": return this.Context.DbMehtods.EqualsNull(model); case "DateIsSame": if (model.Args.Count == 2) return this.Context.DbMehtods.DateIsSameDay(model); else { var dsResult = this.Context.DbMehtods.DateIsSameByType(model); this.Context.Parameters.RemoveAll(it => it.ParameterName == model.Args[2].MemberName.ObjToString()); return dsResult; } case "DateAdd": model.Conext = this.Context; if (model.Args.Count == 2) return this.Context.DbMehtods.DateAddDay(model); else { 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); this.Context.Parameters.RemoveAll(it => it.ParameterName == model.Args[1].MemberName.ObjToString()); return dvResult; case "Between": return this.Context.DbMehtods.Between(model); case "StartsWith": return GetLike(this.Context.DbMehtods.StartsWith(model),iLike); case "EndsWith": return GetLike(this.Context.DbMehtods.EndsWith(model), iLike); case "ToInt32": return this.Context.DbMehtods.ToInt32(model); case "ToInt64": return this.Context.DbMehtods.ToInt64(model); case "ToDate": return this.Context.DbMehtods.ToDate(model); case "ToDateTime": return this.Context.DbMehtods.ToDate(model); case "ToTime": return this.Context.DbMehtods.ToTime(model); case "ToString": if (model.Args.Count > 1) { var dateString2 = this.Context.DbMehtods.GetDateString(model.Args.First().MemberName.ObjToString(), model.Args.Last().MemberValue.ObjToString()); if (IsSqlServerModel()) { return string.Format("FORMAT({0},'{1}','en-US')", model.Args.First().MemberName.ObjToString(), model.Args.Last().MemberValue.ObjToString()); } if (dateString2 != null) return dateString2; return GeDateFormat(model.Args.Last().MemberValue.ObjToString(), model.Args.First().MemberName.ObjToString()); } //Check.Exception(model.Args.Count > 1, "ToString (Format) is not supported, Use ToString().If time formatting can be used it.Date.Year+\"-\"+it.Data.Month+\"-\"+it.Date.Day "); return this.Context.DbMehtods.ToString(model); case "ToVarchar": return this.Context.DbMehtods.ToVarchar(model); case "ToDecimal": return this.Context.DbMehtods.ToDecimal(model); case "ToGuid": return this.Context.DbMehtods.ToGuid(model); case "ToDouble": return this.Context.DbMehtods.ToDouble(model); case "ToBool": return this.Context.DbMehtods.ToBool(model); case "ToBoolean": return this.Context.DbMehtods.ToBool(model); case "Substring": if (model.Args.Count == 2) { model.Args.Add(new MethodCallExpressionArgs() { MemberName="100000", IsMember=true, MemberValue= "100000", }); } model.Conext = this.Context; return this.Context.DbMehtods.Substring(model); case "Replace": return this.Context.DbMehtods.Replace(model); case "Length": return this.Context.DbMehtods.Length(model); case "AggregateSum": return this.Context.DbMehtods.AggregateSum(model); case "AggregateAvg": return this.Context.DbMehtods.AggregateAvg(model); case "AggregateMin": return this.Context.DbMehtods.AggregateMin(model); case "AggregateMax": return this.Context.DbMehtods.AggregateMax(model); case "AggregateCount": return this.Context.DbMehtods.AggregateCount(model); case "AggregateDistinctCount": return this.Context.DbMehtods.AggregateDistinctCount(model); case "MappingColumn": var mappingColumnResult = this.Context.DbMehtods.MappingColumn(model); if (model.Args.Count == 1&& mappingColumnResult.IsNullOrEmpty()) { return model.Args[0].MemberName.ObjToString().TrimStart('\'').TrimEnd('\''); } var isValid = model.Args[0].IsMember && model.Args[1].IsMember == false; //Check.Exception(!isValid, "SqlFunc.MappingColumn parameters error, The property name on the left, string value on the right"); if (model.Args.Count > 1) { this.Context.Parameters.RemoveAll(it => it.ParameterName == model.Args[1].MemberName.ObjToString()); } else { this.Context.Parameters.RemoveAll(it => it.ParameterName == model.Args[0].MemberName.ObjToString()); } if (mappingColumnResult == "") { return model.Args[1].MemberName.ObjToString().TrimStart('\'').TrimEnd('\''); } return mappingColumnResult; case "IsNull": return this.Context.DbMehtods.IsNull(model); case "MergeString": return this.Context.DbMehtods.MergeString(model.Args.Select(it => it.MemberName.ObjToString()).ToArray()); case "SelectAll": case "GetSelfAndAutoFill": this.Context.Parameters.RemoveAll(it => it.ParameterName == model.Args[0].MemberName.ObjToString()); var result1 = this.Context.DbMehtods.GetSelfAndAutoFill(this.Context.GetTranslationColumnName(model.Args[0].MemberValue.ObjToString()), this.Context.IsSingle); if ((model.Args[0].MemberValue + "") == "." && this.Context.IsSingle) { result1 = this.Context.GetTranslationTableName(model.Args[0].MemberName + "", false) + ".*/**/" + result1; } return result1; case "GetDate": if (this.Context?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.SqlServer) { return "GetDate()"; } return this.Context.DbMehtods.GetDate(); case "GetRandom": return this.Context.DbMehtods.GetRandom(); case "CharIndex": return this.Context.DbMehtods.CharIndex(model); case "BitwiseAnd": return this.Context.DbMehtods.BitwiseAnd(model); case "BitwiseInclusiveOR": return this.Context.DbMehtods.BitwiseInclusiveOR(model); case "ToDateShort": return this.Context.DbMehtods.ToDateShort(model); case "Oracle_ToChar": return this.Context.DbMehtods.Oracle_ToChar(model); case "Oracle_ToDate": return this.Context.DbMehtods.Oracle_ToDate(model); case "SqlServer_DateDiff": return this.Context.DbMehtods.SqlServer_DateDiff(model); case "Format": var xx = base.BaseParameter; var result = this.Context.DbMehtods.Format(model); if (this.Context.MethodName== "MappingColumn" || this.Context.MethodName?.StartsWith("Row")==true) { result = this.Context.DbMehtods.FormatRowNumber(model); } this.Context.Parameters.RemoveAll(it => model.Args.Select(x => x.MemberName.ObjToString()).Contains(it.ParameterName)); return result; case "Abs": return this.Context.DbMehtods.Abs(model); case "Round": return this.Context.DbMehtods.Round(model); case "DateDiff": return this.Context.DbMehtods.DateDiff(model); case "GreaterThan": return this.Context.DbMehtods.GreaterThan(model); case "GreaterThanOrEqual": return this.Context.DbMehtods.GreaterThanOrEqual(model); case "LessThan": return this.Context.DbMehtods.LessThan(model); case "LessThanOrEqual": return this.Context.DbMehtods.LessThanOrEqual(model); case "Asc": return this.Context.DbMehtods.Asc(model); case "Desc": return this.Context.DbMehtods.Desc(model); case "Stuff": return this.Context.DbMehtods.Stuff(model); case "RowNumber": return this.Context.DbMehtods.RowNumber(model); case "Rank": return this.Context.DbMehtods.RowNumber(model).Replace("row_number() over(", " rank() over("); case "DenseRank": return this.Context.DbMehtods.RowNumber(model).Replace("row_number() over(", " dense_rank() over("); case "RowCount": return this.Context.DbMehtods.RowCount(model); case "RowSum": return this.Context.DbMehtods.RowSum(model); case "RowMax": return this.Context.DbMehtods.RowMax(model); case "RowMin": return this.Context.DbMehtods.RowMin(model); case "RowAvg": return this.Context.DbMehtods.RowAvg(model); case "Exists": if (model.Args.Count > 1) { this.Context.Parameters.RemoveAll(it => model.Args[1].MemberName.ObjToString().Contains(it.ParameterName)); List conditionalModels = (List)model.Args[1].MemberValue; var sqlObj = this.Context.SugarContext.Context.Queryable().SqlBuilder.ConditionalModelToSql(conditionalModels, 0); var sql = sqlObj.Key; UtilMethods.RepairReplicationParameters(ref sql, sqlObj.Value, 0, "_" + this.Context.ParameterIndex + "_B"); model.Args[1].MemberName = sql; if (sqlObj.Value != null) { this.Context.Parameters.AddRange(sqlObj.Value); } else { return " 1=1 "; } } return this.Context.DbMehtods.Exists(model); case "JsonField": return this.Context.DbMehtods.JsonField(model); case "JsonArrayLength": return this.Context.DbMehtods.JsonArrayLength(model); case "JsonContainsFieldName": return this.Context.DbMehtods.JsonContainsFieldName(model); case "JsonParse": return this.Context.DbMehtods.JsonParse(model); case "JsonLike": return this.Context.DbMehtods.JsonLike(model); case "Collate": return this.Context.DbMehtods.Collate(model); case "AggregateSumNoNull": return this.Context.DbMehtods.AggregateSumNoNull(model); case "JsonListObjectAny": return this.Context.DbMehtods.JsonListObjectAny(model); case "JsonArrayAny": return this.Context.DbMehtods.JsonArrayAny(model); case "CompareTo": return this.Context.DbMehtods.CompareTo(model); case "SplitIn": return this.Context.DbMehtods.SplitIn(model); case "ListAny": this.Context.Result.IsNavicate = true; this.Context.Parameters.RemoveAll(it => model.Args[0].MemberName.ObjToString().Contains(it.ParameterName)); return this.Context.DbMehtods.ListAny(model); case "ListAll": this.Context.Result.IsNavicate = true; this.Context.Parameters.RemoveAll(it => model.Args[0].MemberName.ObjToString().Contains(it.ParameterName)); return this.Context.DbMehtods.ListAll(model); case "Modulo": return this.Context.DbMehtods.Modulo(model); case "Like": return GetLike(this.Context.DbMehtods.Like(model),iLike); case "ToSingle": return this.Context.DbMehtods.ToSingle(model); case "GreaterThan_LinqDynamicCore": return this.Context.DbMehtods.GreaterThan(model); case "LessThan_LinqDynamicCore": return this.Context.DbMehtods.LessThan(model); default: if (typeof(IDbMethods).GetMethods().Any(it => it.Name == name)) { return this.Context.DbMehtods.GetType().GetMethod(name).Invoke(this.Context.DbMehtods,new object[] { model}); } break; } } return null; } private bool IsSqlServerModel() { return this.Context?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.DatabaseModel == DbType.SqlServer; } private string GetLike(string result, bool iLike) { if (iLike) { result = result.Replace(" like ", " ilike "); } return result; } private DbType GetType(string name) { DbType result = DbType.SqlServer; foreach (var item in UtilMethods.EnumToDictionary()) { if (name.StartsWith(item.Value.ToString())) { result = item.Value; break; } } return result; } private bool IsContainsArray(MethodCallExpression express, string methodName, bool isValidNativeMethod) { if (isMemoryExtensionsContainsArray(express, methodName)) { return true; } return !isValidNativeMethod && express.Method.DeclaringType.Namespace.IsIn("System.Collections", "System.Linq", "System.Collections.Generic") && methodName == "Contains"; } private bool isMemoryExtensionsContainsArray(MethodCallExpression express, string methodName) { var isMemoryExtensionsContainsArray = false; if (express.Method.DeclaringType.Name == "MemoryExtensions" && methodName == "Contains") { if (express.Arguments.Count() == 2) { if (express.Arguments.First() is MethodCallExpression callExpression) { if (callExpression.Method.Name == "op_Implicit") { isMemoryExtensionsContainsArray = true; } } } } return isMemoryExtensionsContainsArray; } private bool IsSubMethod(MethodCallExpression express, string methodName) { return SubTools.SubItemsConst.Any(it => it.Name == methodName) && express.Object != null && (express.Object.Type.Name.StartsWith("Subqueryable`")); } private bool CheckMethod(MethodCallExpression expression) { if (expression?.Object?.Type?.Name?.StartsWith("ISugarQueryable`") == true) { Check.ExceptionEasy("Sublookup is implemented using SqlFunc.Subquery(); Queryable objects cannot be used", "子查请使用SqlFunc.Subquery()来实现,不能用Queryable对象"); } if (expression.Method.Name == "SelectAll") { return true; } if (expression.Method.Name == "IndexOf") { return true; } if (expression.Method.Name == "CompareTo") { return true; } if (expression.Method.Name == "Any"&& expression.Arguments.Count()>0&& ExpressionTool.IsVariable(expression.Arguments[0]) ) { return true; } if (expression.Method.Name == "All" && expression.Arguments.Count() > 0 && ExpressionTool.IsVariable(expression.Arguments[0])) { return true; } if (expression.Method.Name == "Format" && expression.Method.DeclaringType == UtilConstants.StringType) { return true; } if (IsExtMethod(expression.Method.Name)) return true; if (IsParseMethod(expression)) return true; if (expression.Method.Name == "IsNullOrEmpty" && expression.Method.DeclaringType == UtilConstants.StringType) { return true; } if (expression.Method.Name == "IsNullOrWhiteSpace" && expression.Method.DeclaringType == UtilConstants.StringType) { return true; } if (expression.Method.ReflectedType().FullName != ExpressionConst.SqlFuncFullName) return false; else return true; } private Type TempParseType; public bool IsParseMethod(MethodCallExpression expression) { if (expression.Method.Name == "Parse" && expression.Method.DeclaringType.IsIn( UtilConstants.DecType, UtilConstants.DateType, UtilConstants.DobType, UtilConstants.GuidType, UtilConstants.FloatType, UtilConstants.ShortType, UtilConstants.LongType, UtilConstants.IntType, UtilConstants.BoolType)) { TempParseType = expression.Method.DeclaringType; return true; } return false; } private static bool IsNot(Expression item) { return item is UnaryExpression && (item as UnaryExpression).NodeType == ExpressionType.Not; } private bool IsDateItemValue(Expression item) { var result = false; if (item is MemberExpression) { var memberExp = item as MemberExpression; if (memberExp != null && memberExp.Expression != null && memberExp.Expression.Type == UtilConstants.DateType) { foreach (var dateType in UtilMethods.EnumToDictionary()) { if (memberExp.Member.Name.EqualCase(dateType.Key)) { result = true; break; } else if (memberExp.Member.Name == "DayOfWeek") { result = true; break; } } } } return result; } private static bool IsDateDate(Expression item) { return item.Type == UtilConstants.DateType && item is MemberExpression && (item as MemberExpression).Member.Name == "Date" && item.ToString() != "DateTime.Now.Date"; } private static bool IsDateValue(Expression item) { return item.Type == UtilConstants.IntType && item is MemberExpression && (item as MemberExpression).Expression != null && (item as MemberExpression).Expression.Type == UtilConstants.DateType && (item as MemberExpression).Expression is MemberExpression && ((item as MemberExpression).Expression as MemberExpression).Member.Name == "Value"; } private bool IsValidNativeMethod(MethodCallExpression express, string methodName) { return MethodMapping.ContainsKey(methodName) && express.Method.DeclaringType.Namespace == ("System"); } private bool IsExtMethod(string methodName) { if (this.Context.SqlFuncServices == null) return false; return this.Context.SqlFuncServices.Select(it => it.UniqueMethodName).Contains(methodName); } private bool IsIfElse(MethodCallExpression express, string methodName) { if (methodName == "End" && express.Object.Type == typeof(CaseWhen)) return true; else return false; } } }