using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; namespace SqlSugar { /// ///Json model to sql /// public abstract partial class SqlBuilderProvider : SqlBuilderAccessory, ISqlBuilder { #region Root public KeyValuePair FuncModelToSql(IFuncModel model) { ObjectFuncModel data = model as ObjectFuncModel; var name = data.FuncName; var parameters = data.Parameters; var dbMethods = this.Context.Queryable().QueryBuilder.LambdaExpressions.DbMehtods; var methods = GetAllMethods(dbMethods); var methodName = GetMethodName(name, methods); var methodInfo = GetMethod(dbMethods, methodName); var pars = methodInfo.GetParameters(); var resSql = ""; var resPars = new List(); resSql = GetSql(parameters, dbMethods, methodName, methodInfo, pars, resPars); return new KeyValuePair(resSql, resPars.ToArray()); } #endregion #region Level2 private string GetSql(List parameters, IDbMethods dbMethods, string methodName, System.Reflection.MethodInfo methodInfo, System.Reflection.ParameterInfo[] pars, List resPars) { string resSql; if (IsNoParameter(pars)) { resSql = GetNoParameterMehtodSql(dbMethods, methodInfo); } else if (IsFormatMethod(methodName)) { resSql = GetFormatMethodSql(parameters, resPars); } else if (IsSqlFuncMethod(pars)) { resSql = GetSqlFuncSql(parameters, dbMethods, methodName, methodInfo, resPars); } else { resSql = GetNoSupportMethodSql(methodInfo); } return resSql; } private static System.Reflection.MethodInfo GetMethod(IDbMethods dbMethods, string methodName) { return dbMethods.GetType().GetMethods() .Where(it => it.Name == methodName) .Where(it => it.Name != "Equals" || it.GetParameters().Length == 1 && it.GetParameters().First().ParameterType == typeof(MethodCallExpressionModel)) .FirstOrDefault(); } private static string GetMethodName(string name, List methods) { var result = methods.FirstOrDefault(it => name.EqualCase("SqlFunc_" + it) || name.EqualCase(it)); Check.Exception(result == null, $" { name } is error "); return result; } private static List GetAllMethods(IDbMethods dbMethods) { return new ReflectionInoCacheService().GetOrCreate("Json2SqlGetFuncSql", () => dbMethods.GetType() .GetMethods().Where(it => it.Name != "GetHashCode").Select(it => it.Name).ToList()); } #endregion #region Level3 private static string GetNoSupportMethodSql(System.Reflection.MethodInfo methodInfo) { throw new Exception(methodInfo.Name); } private string GetSqlFuncSql(List parameters, IDbMethods dbMethods, string methodName, System.Reflection.MethodInfo methodInfo, List resPars) { string resSql; var args = new List(); foreach (var item in parameters) { var value = GetSqlPart(item, resPars); args.Add(new MethodCallExpressionArgs { MemberName = value, MemberValue = value, IsMember = true }); } resSql = methodInfo.Invoke(dbMethods, new object[] { new MethodCallExpressionModel() { Name=methodName, Args=args } }).ObjToString(); return resSql; } private string GetFormatMethodSql(List parameters, List resPars) { string resSql; var objects = new List(); foreach (var item in parameters) { var value = GetSqlPart(item, resPars); objects.Add(value.ObjToString()); } resSql = string.Join(" ", string.Join(" ", objects)); return resSql; } private static string GetNoParameterMehtodSql(IDbMethods dbMethods, System.Reflection.MethodInfo methodInfo) { return methodInfo.Invoke(dbMethods, new object[] { }).ObjToString(); } #endregion #region Helper private static bool IsSqlFuncMethod(System.Reflection.ParameterInfo[] pars) { return pars.First().ParameterType == typeof(MethodCallExpressionModel); } private static bool IsFormatMethod(string methodName) { return methodName.EqualCase("format"); } private static bool IsNoParameter(System.Reflection.ParameterInfo[] pars) { return pars.Length == 0; } #endregion } }