SqlBuilderProvider_Condition.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Text.RegularExpressions;
  7. using System.Threading.Tasks;
  8. namespace SqlSugar
  9. {
  10. public abstract partial class SqlBuilderProvider : SqlBuilderAccessory, ISqlBuilder
  11. {
  12. #region Core
  13. public KeyValuePair<string, SugarParameter[]> ConditionalModelToSql(List<IConditionalModel> models, int beginIndex = 0)
  14. {
  15. if (models.IsNullOrEmpty()) return new KeyValuePair<string, SugarParameter[]>();
  16. StringBuilder builder = new StringBuilder();
  17. List<SugarParameter> parameters = new List<SugarParameter>();
  18. var sqlBuilder = InstanceFactory.GetSqlbuilder(this.Context.CurrentConnectionConfig);
  19. var mainIndex = 0;
  20. var indexTree = 0;
  21. foreach (var model in models)
  22. {
  23. if (model is ConditionalModel)
  24. {
  25. var item = model as ConditionalModel;
  26. if (item.CustomConditionalFunc != null)
  27. {
  28. var colIndex = mainIndex + beginIndex;
  29. var colType = colIndex == 0 ? "" : "AND";
  30. var custom = item.CustomConditionalFunc.GetConditionalSql(item, colIndex);
  31. parameters.AddRange(custom.Value);
  32. builder.AppendFormat(" " + colType + " " + custom.Key);
  33. mainIndex++;
  34. continue;
  35. }
  36. else if (item.FieldName == UtilMethods.FiledNameSql())
  37. {
  38. builder.Append(item.FieldValue);
  39. continue;
  40. }
  41. var index = mainIndex + beginIndex;
  42. var type = index == 0 ? "" : "AND";
  43. if (beginIndex > 0)
  44. {
  45. type = null;
  46. }
  47. string temp = " {0} {1} {2} {3} ";
  48. string parameterName = string.Format("{0}Condit{1}{2}", sqlBuilder.SqlParameterKeyWord, item.FieldName, index);
  49. if (this.Context?.CurrentConnectionConfig?.MoreSettings?.MaxParameterNameLength > 0&& parameterName.Length> this.Context?.CurrentConnectionConfig?.MoreSettings?.MaxParameterNameLength)
  50. {
  51. parameterName = string.Format("{0}Condit{1}{2}", sqlBuilder.SqlParameterKeyWord,item.FieldName.GetHashCode().ToString().Replace("-", ""), index);
  52. }
  53. if (parameterName.Contains("."))
  54. {
  55. parameterName = parameterName.Replace(".", "_");
  56. }
  57. if (parameterName.Contains("["))
  58. {
  59. parameterName = parameterName.Replace("[", "_");
  60. }
  61. if (parameterName.Contains("]"))
  62. {
  63. parameterName = parameterName.Replace("]", "_");
  64. }
  65. if (!string.IsNullOrEmpty(this.SqlTranslationLeft) && parameterName.Contains(this.SqlTranslationLeft))
  66. {
  67. parameterName = parameterName.Replace(this.SqlTranslationLeft, "_");
  68. }
  69. string oldName = item.FieldName;
  70. item.FieldName = GetTranslationColumnName(item.FieldName);
  71. item.FieldName = item.FieldName.ToCheckField();
  72. switch (item.ConditionalType)
  73. {
  74. case ConditionalType.Equal:
  75. Equal(builder, parameters, item, type, temp, parameterName);
  76. break;
  77. case ConditionalType.Like:
  78. builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), "LIKE", parameterName);
  79. parameters.Add(new SugarParameter(parameterName, "%" + item.FieldValue + "%"));
  80. break;
  81. case ConditionalType.GreaterThan:
  82. builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), ">", parameterName);
  83. parameters.Add(new SugarParameter(parameterName, GetFieldValue(item)));
  84. break;
  85. case ConditionalType.GreaterThanOrEqual:
  86. builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), ">=", parameterName);
  87. parameters.Add(new SugarParameter(parameterName, GetFieldValue(item)));
  88. break;
  89. case ConditionalType.LessThan:
  90. builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), "<", parameterName);
  91. parameters.Add(new SugarParameter(parameterName, GetFieldValue(item)));
  92. break;
  93. case ConditionalType.LessThanOrEqual:
  94. builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), "<=", parameterName);
  95. parameters.Add(new SugarParameter(parameterName, GetFieldValue(item)));
  96. break;
  97. case ConditionalType.In:
  98. In(builder, item, type, temp);
  99. //parameters.Add(new SugarParameter(parameterName, item.FieldValue));
  100. break;
  101. case ConditionalType.NotIn:
  102. NotIn(builder, parameters, item, type, temp, parameterName);
  103. break;
  104. case ConditionalType.LikeLeft:
  105. builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), "LIKE", parameterName);
  106. parameters.Add(new SugarParameter(parameterName, item.FieldValue + "%"));
  107. break;
  108. case ConditionalType.NoLike:
  109. builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), " NOT LIKE", parameterName);
  110. parameters.Add(new SugarParameter(parameterName, "%" + item.FieldValue + "%"));
  111. break;
  112. case ConditionalType.LikeRight:
  113. builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), "LIKE", parameterName);
  114. parameters.Add(new SugarParameter(parameterName, "%" + item.FieldValue));
  115. break;
  116. case ConditionalType.NoEqual:
  117. builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), "<>", parameterName);
  118. parameters.Add(new SugarParameter(parameterName, GetFieldValue(item)));
  119. break;
  120. case ConditionalType.IsNullOrEmpty:
  121. builder.AppendFormat(" {0} (({1}) OR ({2})) ", type, item.FieldName.ToSqlFilter() + " IS NULL ", item.FieldName.ToSqlFilter() + " = '' ");
  122. parameters.Add(new SugarParameter(parameterName, item.FieldValue));
  123. break;
  124. case ConditionalType.IsNot:
  125. IsNot(builder, parameters, item, type, temp, parameterName);
  126. break;
  127. case ConditionalType.EqualNull:
  128. EqualNull(builder, parameters, item, type, temp, parameterName);
  129. break;
  130. case ConditionalType.InLike:
  131. InLike(builder, parameters, item, index, type, parameterName);
  132. break;
  133. default:
  134. break;
  135. }
  136. item.FieldName = oldName;
  137. }
  138. else if (model is ConditionalCollections)
  139. {
  140. var item = model as ConditionalCollections;
  141. if (item != null && item.ConditionalList.HasValue())
  142. {
  143. foreach (var con in item.ConditionalList)
  144. {
  145. var index = item.ConditionalList.IndexOf(con);
  146. var isFirst = index == 0;
  147. var isLast = index == (item.ConditionalList.Count - 1);
  148. if (models.IndexOf(item) == 0 && index == 0 && beginIndex == 0)
  149. {
  150. builder.AppendFormat(" ( ");
  151. }
  152. else if (isFirst)
  153. {
  154. builder.AppendFormat(" {0} ( ", con.Key.ToString().ToUpper());
  155. }
  156. List<IConditionalModel> conModels = new List<IConditionalModel>();
  157. conModels.Add(con.Value);
  158. var childSqlInfo = ConditionalModelToSql(conModels, 1000 * (1 + index) + models.IndexOf(item));
  159. if (!isFirst && con.Value.FieldName != $"[value=sql{UtilConstants.ReplaceKey}]")
  160. {
  161. builder.AppendFormat(" {0} ", con.Key.ToString().ToUpper());
  162. }
  163. builder.Append(childSqlInfo.Key);
  164. if (conModels?.FirstOrDefault() is ConditionalModel conModel)
  165. {
  166. if (conModel.CustomConditionalFunc != null)
  167. {
  168. builder.Replace(" AND ( AND", " AND ( ");
  169. builder.Replace(" OR ( AND", " OR ( ");
  170. builder.Replace(" ( AND ", " ( ");
  171. builder.Replace(" ( OR ", " ( ");
  172. }
  173. }
  174. parameters.AddRange(childSqlInfo.Value);
  175. if (isLast)
  176. {
  177. builder.Append(" ) ");
  178. }
  179. else
  180. {
  181. }
  182. }
  183. }
  184. }
  185. else
  186. {
  187. var item = model as ConditionalTree;
  188. BuilderTree(builder, item, ref indexTree, parameters, ref mainIndex);
  189. }
  190. mainIndex++;
  191. }
  192. return new KeyValuePair<string, SugarParameter[]>(builder.ToString(), parameters.ToArray());
  193. }
  194. #endregion
  195. #region Case Method
  196. private static void InLike(StringBuilder builder, List<SugarParameter> parameters, ConditionalModel item, int index, string type, string parameterName)
  197. {
  198. var array = (item.FieldValue + "").Split(',').ToList();
  199. List<string> sqls = new List<string>();
  200. int i = 0;
  201. foreach (var val in array)
  202. {
  203. var itemParameterName = $"{parameterName}{index}{i}";
  204. sqls.Add(item.FieldName.ToSqlFilter() + " LIKE " + itemParameterName);
  205. parameters.Add(new SugarParameter(itemParameterName, "%" + val + "%"));
  206. i++;
  207. }
  208. builder.Append($" {type} ({string.Join(" OR ", sqls)}) ");
  209. }
  210. private static void EqualNull(StringBuilder builder, List<SugarParameter> parameters, ConditionalModel item, string type, string temp, string parameterName)
  211. {
  212. if (GetFieldValue(item) == null)
  213. {
  214. builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), " IS ", " NULL ");
  215. }
  216. else
  217. {
  218. builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), "=", parameterName);
  219. parameters.Add(new SugarParameter(parameterName, GetFieldValue(item)));
  220. }
  221. }
  222. private static void IsNot(StringBuilder builder, List<SugarParameter> parameters, ConditionalModel item, string type, string temp, string parameterName)
  223. {
  224. if (item.FieldValue == null)
  225. {
  226. builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), " IS NOT ", "NULL");
  227. }
  228. else
  229. {
  230. builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), "<>", parameterName);
  231. parameters.Add(new SugarParameter(parameterName, item.FieldValue));
  232. }
  233. }
  234. private static void NotIn(StringBuilder builder, List<SugarParameter> parameters, ConditionalModel item, string type, string temp, string parameterName)
  235. {
  236. if (item.FieldValue == null) item.FieldValue = string.Empty;
  237. var inValue2 = ("(" + item.FieldValue.Split(',').ToJoinSqlInVals() + ")");
  238. if (item.CSharpTypeName.HasValue() && UtilMethods.IsNumber(item.CSharpTypeName))
  239. {
  240. inValue2 = inValue2.Replace("'", "");
  241. }
  242. else if (inValue2.Contains("'null'"))
  243. {
  244. inValue2 = inValue2.Replace("'null'", "null");
  245. }
  246. else if (inValue2.Contains("[null]"))
  247. {
  248. inValue2 = inValue2.Replace("[null]", "null");
  249. }
  250. builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), "NOT IN", inValue2);
  251. parameters.Add(new SugarParameter(parameterName, item.FieldValue));
  252. }
  253. private void In(StringBuilder builder, ConditionalModel item, string type, string temp)
  254. {
  255. if (item.FieldValue == null) item.FieldValue = string.Empty;
  256. var inValue1 = string.Empty;
  257. var inArray=item.FieldValue.Split(',');
  258. var pageSize = 1000;
  259. if (inArray.Length > pageSize&&this.Context.CurrentConnectionConfig.DbType==DbType.Oracle)
  260. {
  261. InBig(builder,item,type,temp,inArray, pageSize);
  262. return;
  263. }
  264. inValue1 = In_GetInValue(item, inArray);
  265. if (item.CSharpTypeName.HasValue() && UtilMethods.IsNumber(item.CSharpTypeName))
  266. {
  267. inValue1 = inValue1.Replace("'", "");
  268. }
  269. else if (inValue1.Contains("'null'"))
  270. {
  271. inValue1 = inValue1.Replace("'null'", "null");
  272. }
  273. else if (inValue1.Contains("[comma]"))
  274. {
  275. inValue1 = inValue1.Replace("[comma]", ",");
  276. }
  277. else if (inValue1.Contains("[null]"))
  278. {
  279. inValue1 = inValue1.Replace("[null]", "null");
  280. }
  281. if (item.CSharpTypeName.EqualCase("guid") && inValue1 == "('')")
  282. {
  283. inValue1 = $"('{Guid.Empty.ToString()}')";
  284. }
  285. else if (inValue1 == "()")
  286. {
  287. inValue1 = $"(NULL)";
  288. }
  289. if (inArray.Length == 1)
  290. {
  291. builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), "=", inValue1.TrimStart('(').TrimEnd(')'));
  292. }
  293. else
  294. {
  295. builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), "IN", inValue1);
  296. }
  297. }
  298. private void InBig(StringBuilder builder, ConditionalModel item, string type, string temp, string[] inArray, int pageSize)
  299. {
  300. var sqlList = new List<string>();
  301. this.Context.Utilities.PageEach(inArray, pageSize, items =>
  302. {
  303. if (item.CSharpTypeName.EqualCase("string") || item.CSharpTypeName == null)
  304. {
  305. sqlList.Add("(" + item.FieldName.ToSqlFilter() + " IN (" + items.Distinct().ToArray().ToJoinSqlInVals() + "))");
  306. }
  307. else
  308. {
  309. sqlList.Add("(" + item.FieldName.ToSqlFilter() + " IN (" + items.Select(it => it == "" ? "null" : it).Distinct().ToArray().ToJoinSqlInVals() + "))");
  310. }
  311. });
  312. var inValue1 = $" {string.Join(" OR ",sqlList)} ";
  313. if (item.CSharpTypeName.HasValue() && UtilMethods.IsNumber(item.CSharpTypeName))
  314. {
  315. inValue1 = inValue1.Replace("'", "");
  316. }
  317. builder.AppendFormat(temp, type, "", " ", inValue1);
  318. }
  319. private static string In_GetInValue(ConditionalModel item,string[] inArray)
  320. {
  321. string inValue1;
  322. if (item.CSharpTypeName.EqualCase("string") || item.CSharpTypeName == null)
  323. {
  324. inValue1 = ("(" + inArray.Distinct().ToArray().ToJoinSqlInVals() + ")");
  325. }
  326. else
  327. {
  328. inValue1 = ("(" + inArray.Select(it => it == "" ? "null" : it).Distinct().ToArray().ToJoinSqlInVals() + ")");
  329. }
  330. return inValue1;
  331. }
  332. private static void Equal(StringBuilder builder, List<SugarParameter> parameters, ConditionalModel item, string type, string temp, string parameterName)
  333. {
  334. if (item.FieldValue != null && item.FieldValue == "null" && item.FieldValue != "[null]")
  335. {
  336. builder.AppendFormat($" {item.FieldName.ToSqlFilter()} is null ");
  337. }
  338. else
  339. {
  340. if (item.FieldValue == "[null]")
  341. {
  342. item.FieldValue = "null";
  343. }
  344. builder.AppendFormat(temp, type, item.FieldName.ToSqlFilter(), "=", parameterName);
  345. parameters.Add(new SugarParameter(parameterName, GetFieldValue(item)));
  346. }
  347. }
  348. #endregion
  349. #region ConditionalCollections
  350. private void BuilderTree(StringBuilder builder, ConditionalTree item, ref int indexTree, List<SugarParameter> parameters, ref int mainIndex)
  351. {
  352. var conditionals = ToConditionalCollections(item, ref indexTree, parameters);
  353. var sqlobj = ConditionalModelToSql(new List<IConditionalModel> { conditionals }, mainIndex);
  354. var sql = sqlobj.Key;
  355. RepairReplicationParameters(ref sql, sqlobj.Value, indexTree);
  356. parameters.AddRange(sqlobj.Value);
  357. var buiderSql = sql;
  358. builder.Append(buiderSql);
  359. indexTree++;
  360. }
  361. private ConditionalCollections ToConditionalCollections(ConditionalTree item, ref int indexTree, List<SugarParameter> parameters)
  362. {
  363. List<KeyValuePair<WhereType, ConditionalModel>> list = new List<KeyValuePair<WhereType, ConditionalModel>>();
  364. var index = 0;
  365. foreach (var it in item.ConditionalList)
  366. {
  367. ConditionalModel model = new ConditionalModel();
  368. if (it.Value is ConditionalModel)
  369. {
  370. model = (ConditionalModel)it.Value;
  371. }
  372. else
  373. {
  374. var tree = it.Value as ConditionalTree;
  375. var con = ToConditionalCollections(tree, ref indexTree, parameters);
  376. var sqlobj = ConditionalModelToSql(new List<IConditionalModel> { con }, index);
  377. var sql = sqlobj.Key;
  378. if (sql.StartsWith(" NULL "))
  379. {
  380. sql = Regex.Replace(sql, "^ NULL ", it.Key.ToString().ToUpper());
  381. }
  382. RepairReplicationParameters(ref sql, sqlobj.Value, indexTree);
  383. model = new ConditionalModel()
  384. {
  385. FieldName = $"[value=sql{UtilConstants.ReplaceKey}]",
  386. FieldValue = sql
  387. };
  388. parameters.AddRange(sqlobj.Value);
  389. indexTree++;
  390. }
  391. list.Add(new KeyValuePair<WhereType, ConditionalModel>(it.Key, model));
  392. index++;
  393. }
  394. var result = new ConditionalCollections()
  395. {
  396. ConditionalList = list
  397. };
  398. return result;
  399. }
  400. #endregion
  401. }
  402. }