FuncModelToSql.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Text.RegularExpressions;
  6. namespace SqlSugar
  7. {
  8. /// <summary>
  9. ///Json model to sql
  10. /// </summary>
  11. public abstract partial class SqlBuilderProvider : SqlBuilderAccessory, ISqlBuilder
  12. {
  13. #region Root
  14. public KeyValuePair<string, SugarParameter[]> FuncModelToSql(IFuncModel model)
  15. {
  16. ObjectFuncModel data = model as ObjectFuncModel;
  17. var name = data.FuncName;
  18. var parameters = data.Parameters;
  19. var dbMethods = this.Context.Queryable<object>().QueryBuilder.LambdaExpressions.DbMehtods;
  20. var methods = GetAllMethods(dbMethods);
  21. var methodName = GetMethodName(name, methods);
  22. var methodInfo = GetMethod(dbMethods, methodName);
  23. var pars = methodInfo.GetParameters();
  24. var resSql = "";
  25. var resPars = new List<SugarParameter>();
  26. resSql = GetSql(parameters, dbMethods, methodName, methodInfo, pars, resPars);
  27. if (name.EqualCase("MappingColumn"))
  28. {
  29. if (!(this.Context?. CurrentConnectionConfig?.MoreSettings?.EnableModelFuncMappingColumn == true))
  30. {
  31. Check.ExceptionEasy("Enable MappingColumn need in ConnectionConfig - > MoreSettings - > EnableModelFuncMappingColumn set to true", "MappingColumn考虑到风险情况需要开启才能使用,请在 ConnectionConfig->MoreSettings->EnableModelFuncMappingColumn设置为true");
  32. }
  33. resSql = parameters.First() +"";
  34. }
  35. return new KeyValuePair<string, SugarParameter[]>(resSql, resPars.ToArray());
  36. }
  37. #endregion
  38. #region Level2
  39. private string GetSql(List<object> parameters, IDbMethods dbMethods, string methodName, System.Reflection.MethodInfo methodInfo, System.Reflection.ParameterInfo[] pars, List<SugarParameter> resPars)
  40. {
  41. string resSql;
  42. if (IsNoParameter(pars))
  43. {
  44. resSql = GetNoParameterMehtodSql(dbMethods, methodInfo);
  45. }
  46. else if (IsFormatMethod(methodName))
  47. {
  48. resSql = GetFormatMethodSql(parameters, resPars);
  49. }
  50. else if (IsSqlFuncMethod(pars))
  51. {
  52. resSql = GetSqlFuncSql(parameters, dbMethods, methodName, methodInfo, resPars);
  53. }
  54. else if (IsMergeStringMethod(methodName))
  55. {
  56. resSql = GetSqlFuncSql(parameters, dbMethods, methodName, methodInfo, resPars);
  57. }
  58. else
  59. {
  60. resSql = GetNoSupportMethodSql(methodInfo);
  61. }
  62. return resSql;
  63. }
  64. private static System.Reflection.MethodInfo GetMethod(IDbMethods dbMethods, string methodName)
  65. {
  66. return dbMethods.GetType().GetMethods()
  67. .Where(it => it.Name == methodName)
  68. .Where(it => it.Name != "Equals" || it.GetParameters().Length == 1 && it.GetParameters().First().ParameterType == typeof(MethodCallExpressionModel))
  69. .FirstOrDefault();
  70. }
  71. private static string GetMethodName(string name, List<string> methods)
  72. {
  73. var result = methods.FirstOrDefault(it => name.EqualCase("SqlFunc_" + it) || name.EqualCase(it));
  74. Check.Exception(result == null, $" { name } is error ");
  75. return result;
  76. }
  77. private static List<string> GetAllMethods(IDbMethods dbMethods)
  78. {
  79. return new ReflectionInoCacheService().GetOrCreate("Json2SqlGetFuncSql", () =>
  80. dbMethods.GetType()
  81. .GetMethods().Where(it => it.Name != "GetHashCode").Select(it => it.Name).ToList());
  82. }
  83. #endregion
  84. #region Level3
  85. private static string GetNoSupportMethodSql(System.Reflection.MethodInfo methodInfo)
  86. {
  87. throw new Exception(methodInfo.Name);
  88. }
  89. private string GetSqlFuncSql(List<object> parameters, IDbMethods dbMethods, string methodName, System.Reflection.MethodInfo methodInfo, List<SugarParameter> resPars)
  90. {
  91. string resSql;
  92. var args = new List<MethodCallExpressionArgs>();
  93. int i = 0;
  94. foreach (var item in parameters)
  95. {
  96. i++;
  97. string value = null;
  98. if (methodName.IsIn("ContainsArray", "ContainsArrayUseSqlParameters") &&i==1)
  99. {
  100. var first = Regex.Split(item+"", ":").First();
  101. var last = Regex.Split(item + "", ":").Last();
  102. object[] array = this.Context.Utilities.DeserializeObject<object[]>(last);
  103. value = GetParameterName(resPars, array);
  104. }
  105. else
  106. {
  107. value = GetSqlPart(item, resPars);
  108. }
  109. args.Add(new MethodCallExpressionArgs
  110. {
  111. MemberName = value,
  112. MemberValue = resPars.FirstOrDefault(it => it.ParameterName == value)?.Value?? value,
  113. IsMember = true
  114. });
  115. }
  116. if (IsMergeStringMethod(methodName))
  117. {
  118. return methodInfo.Invoke(dbMethods, new object[] { args.Select(it=>it.MemberName.ObjToString()).ToArray() }).ObjToString();
  119. }
  120. resSql = methodInfo.Invoke(dbMethods, new object[] { new MethodCallExpressionModel() {
  121. Name=methodName,
  122. Args=args
  123. } }).ObjToString();
  124. return resSql;
  125. }
  126. private string GetFormatMethodSql(List<object> parameters, List<SugarParameter> resPars)
  127. {
  128. string resSql;
  129. var objects = new List<string>();
  130. foreach (var item in parameters)
  131. {
  132. var value = GetSqlPart(item, resPars);
  133. objects.Add(value.ObjToString());
  134. }
  135. resSql = string.Join(" ", string.Join(" ", objects));
  136. return resSql;
  137. }
  138. private static string GetNoParameterMehtodSql(IDbMethods dbMethods, System.Reflection.MethodInfo methodInfo)
  139. {
  140. return methodInfo.Invoke(dbMethods, new object[] { }).ObjToString();
  141. }
  142. #endregion
  143. #region Helper
  144. private static bool IsMergeStringMethod(string methodName)
  145. {
  146. return methodName == "MergeString";
  147. }
  148. private static bool IsSqlFuncMethod(System.Reflection.ParameterInfo[] pars)
  149. {
  150. return pars.First().ParameterType == typeof(MethodCallExpressionModel);
  151. }
  152. private static bool IsFormatMethod(string methodName)
  153. {
  154. return methodName.EqualCase("format");
  155. }
  156. private static bool IsNoParameter(System.Reflection.ParameterInfo[] pars)
  157. {
  158. return pars.Length == 0;
  159. }
  160. #endregion
  161. }
  162. }