You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

206 lines
6.8 KiB

2 years ago
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Linq;
  5. using System.Linq.Expressions;
  6. namespace SqlSugar
  7. {
  8. public class InsertBuilder : IDMLBuilder
  9. {
  10. #region Init
  11. public InsertBuilder()
  12. {
  13. this.sql = new StringBuilder();
  14. this.Parameters = new List<SugarParameter>();
  15. this.DbColumnInfoList = new List<DbColumnInfo>();
  16. }
  17. #endregion Init
  18. #region Common Properties
  19. public SqlSugarClient Context { get; set; }
  20. public ILambdaExpressions LambdaExpressions { get; set; }
  21. public ISqlBuilder Builder { get; set; }
  22. public StringBuilder sql { get; set; }
  23. public List<SugarParameter> Parameters { get; set; }
  24. public string TableWithString { get; set; }
  25. public List<DbColumnInfo> DbColumnInfoList { get; set; }
  26. public bool IsNoInsertNull { get; set; }
  27. public bool IsReturnIdentity { get; set; }
  28. public EntityInfo EntityInfo { get; set; }
  29. public Dictionary<string, int> OracleSeqInfoList { get; set; }
  30. #endregion Common Properties
  31. #region SqlTemplate
  32. public virtual string SqlTemplate
  33. {
  34. get
  35. {
  36. if (IsReturnIdentity)
  37. {
  38. return @"INSERT INTO {0}
  39. ({1})
  40. VALUES
  41. ({2}) ;SELECT SCOPE_IDENTITY();";
  42. }
  43. else
  44. {
  45. return @"INSERT INTO {0}
  46. ({1})
  47. VALUES
  48. ({2}) ;";
  49. }
  50. }
  51. }
  52. public virtual string SqlTemplateBatch
  53. {
  54. get
  55. {
  56. return "INSERT {0} ({1})";
  57. }
  58. }
  59. public virtual string SqlTemplateBatchSelect
  60. {
  61. get
  62. {
  63. return "{0} AS {1}";
  64. }
  65. }
  66. public virtual string SqlTemplateBatchUnion
  67. {
  68. get
  69. {
  70. return "\t\r\nUNION ALL ";
  71. }
  72. }
  73. #endregion SqlTemplate
  74. #region Methods
  75. public virtual void Clear()
  76. {
  77. }
  78. public virtual string GetTableNameString
  79. {
  80. get
  81. {
  82. var result = Builder.GetTranslationTableName(EntityInfo.EntityName);
  83. result += UtilConstants.Space;
  84. if (this.TableWithString.HasValue())
  85. {
  86. result += TableWithString + UtilConstants.Space;
  87. }
  88. return result;
  89. }
  90. }
  91. public virtual ExpressionResult GetExpressionValue(Expression expression, ResolveExpressType resolveType)
  92. {
  93. var resolveExpress = this.LambdaExpressions;
  94. this.LambdaExpressions.Clear();
  95. resolveExpress.MappingColumns = Context.MappingColumns;
  96. resolveExpress.MappingTables = Context.MappingTables;
  97. resolveExpress.IgnoreComumnList = Context.IgnoreColumns;
  98. resolveExpress.SqlFuncServices = Context.CurrentConnectionConfig.ConfigureExternalServices?.SqlFuncServices;
  99. resolveExpress.Resolve(expression, resolveType);
  100. this.Parameters.AddRange(resolveExpress.Parameters);
  101. var result = resolveExpress.Result;
  102. return result;
  103. }
  104. public virtual string ToSqlString()
  105. {
  106. if (IsNoInsertNull)
  107. {
  108. DbColumnInfoList = DbColumnInfoList.Where(it => it.Value != null).ToList();
  109. }
  110. var groupList = DbColumnInfoList.GroupBy(it => it.TableId).ToList();
  111. var isSingle = groupList.Count() == 1;
  112. var columnsString = string.Join(",", groupList.First().Select(it => Builder.GetTranslationColumnName(it.DbColumnName)));
  113. if (isSingle)
  114. {
  115. var columnParametersString = string.Join(",", this.DbColumnInfoList.Select(it => Builder.SqlParameterKeyWord + it.DbColumnName));
  116. return string.Format(SqlTemplate, GetTableNameString, columnsString, columnParametersString);
  117. }
  118. else
  119. {
  120. var batchInsetrSql = new StringBuilder();
  121. var pageSize = 200;
  122. var pageIndex = 1;
  123. var totalRecord = groupList.Count;
  124. var pageCount = (totalRecord + pageSize - 1) / pageSize;
  125. while (pageCount >= pageIndex)
  126. {
  127. batchInsetrSql.AppendFormat(SqlTemplateBatch, GetTableNameString, columnsString);
  128. var i = 0;
  129. foreach (var columns in groupList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList())
  130. {
  131. var isFirst = i == 0;
  132. if (!isFirst)
  133. {
  134. batchInsetrSql.Append(SqlTemplateBatchUnion);
  135. }
  136. batchInsetrSql.Append("\r\n SELECT " + string.Join(",", columns.Select(it => string.Format(SqlTemplateBatchSelect, FormatValue(it.Value), Builder.GetTranslationColumnName(it.DbColumnName)))));
  137. ++i;
  138. }
  139. pageIndex++;
  140. batchInsetrSql.Append("\r\n;\r\n");
  141. }
  142. return batchInsetrSql.ToString();
  143. }
  144. }
  145. public virtual object FormatValue(object value)
  146. {
  147. if (value == null)
  148. {
  149. return "NULL";
  150. }
  151. else
  152. {
  153. var type = value.GetType();
  154. if (type == UtilConstants.DateType)
  155. {
  156. var date = value.ObjToDate();
  157. if (date < Convert.ToDateTime("1900-1-1"))
  158. {
  159. date = Convert.ToDateTime("1900-1-1");
  160. }
  161. return "'" + date.ToString("yyyy-MM-dd HH:mm:ss.fff") + "'";
  162. }
  163. else if (type == UtilConstants.ByteArrayType)
  164. {
  165. var bytesString = "0x" + BitConverter.ToString((byte[])value);
  166. return bytesString;
  167. }
  168. else if (type.IsEnum())
  169. {
  170. return Convert.ToInt64(value);
  171. }
  172. else if (type == UtilConstants.BoolType)
  173. {
  174. return value.ObjToBool() ? "1" : "0";
  175. }
  176. else if (type == UtilConstants.StringType || type == UtilConstants.ObjType)
  177. {
  178. return "N'" + value.ToString().ToSqlFilter() + "'";
  179. }
  180. else
  181. {
  182. return "N'" + value.ToString() + "'";
  183. }
  184. }
  185. }
  186. #endregion Methods
  187. }
  188. }