using System; using System.Collections.Generic; using System.Text; using System.Linq; using System.Linq.Expressions; namespace SqlSugar { public class InsertBuilder : IDMLBuilder { #region Init public InsertBuilder() { this.sql = new StringBuilder(); this.Parameters = new List(); this.DbColumnInfoList = new List(); } #endregion Init #region Common Properties public SqlSugarClient Context { get; set; } public ILambdaExpressions LambdaExpressions { get; set; } public ISqlBuilder Builder { get; set; } public StringBuilder sql { get; set; } public List Parameters { get; set; } public string TableWithString { get; set; } public List DbColumnInfoList { get; set; } public bool IsNoInsertNull { get; set; } public bool IsReturnIdentity { get; set; } public EntityInfo EntityInfo { get; set; } public Dictionary OracleSeqInfoList { get; set; } #endregion Common Properties #region SqlTemplate public virtual string SqlTemplate { get { if (IsReturnIdentity) { return @"INSERT INTO {0} ({1}) VALUES ({2}) ;SELECT SCOPE_IDENTITY();"; } else { return @"INSERT INTO {0} ({1}) VALUES ({2}) ;"; } } } public virtual string SqlTemplateBatch { get { return "INSERT {0} ({1})"; } } public virtual string SqlTemplateBatchSelect { get { return "{0} AS {1}"; } } public virtual string SqlTemplateBatchUnion { get { return "\t\r\nUNION ALL "; } } #endregion SqlTemplate #region Methods public virtual void Clear() { } public virtual string GetTableNameString { get { var result = Builder.GetTranslationTableName(EntityInfo.EntityName); result += UtilConstants.Space; if (this.TableWithString.HasValue()) { result += TableWithString + UtilConstants.Space; } return result; } } public virtual ExpressionResult GetExpressionValue(Expression expression, ResolveExpressType resolveType) { var resolveExpress = this.LambdaExpressions; this.LambdaExpressions.Clear(); resolveExpress.MappingColumns = Context.MappingColumns; resolveExpress.MappingTables = Context.MappingTables; resolveExpress.IgnoreComumnList = Context.IgnoreColumns; resolveExpress.SqlFuncServices = Context.CurrentConnectionConfig.ConfigureExternalServices?.SqlFuncServices; resolveExpress.Resolve(expression, resolveType); this.Parameters.AddRange(resolveExpress.Parameters); var result = resolveExpress.Result; return result; } public virtual string ToSqlString() { if (IsNoInsertNull) { DbColumnInfoList = DbColumnInfoList.Where(it => it.Value != null).ToList(); } var groupList = DbColumnInfoList.GroupBy(it => it.TableId).ToList(); var isSingle = groupList.Count() == 1; var columnsString = string.Join(",", groupList.First().Select(it => Builder.GetTranslationColumnName(it.DbColumnName))); if (isSingle) { var columnParametersString = string.Join(",", this.DbColumnInfoList.Select(it => Builder.SqlParameterKeyWord + it.DbColumnName)); return string.Format(SqlTemplate, GetTableNameString, columnsString, columnParametersString); } else { var batchInsetrSql = new StringBuilder(); var pageSize = 200; var pageIndex = 1; var totalRecord = groupList.Count; var pageCount = (totalRecord + pageSize - 1) / pageSize; while (pageCount >= pageIndex) { batchInsetrSql.AppendFormat(SqlTemplateBatch, GetTableNameString, columnsString); var i = 0; foreach (var columns in groupList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList()) { var isFirst = i == 0; if (!isFirst) { batchInsetrSql.Append(SqlTemplateBatchUnion); } batchInsetrSql.Append("\r\n SELECT " + string.Join(",", columns.Select(it => string.Format(SqlTemplateBatchSelect, FormatValue(it.Value), Builder.GetTranslationColumnName(it.DbColumnName))))); ++i; } pageIndex++; batchInsetrSql.Append("\r\n;\r\n"); } return batchInsetrSql.ToString(); } } public virtual object FormatValue(object value) { if (value == null) { return "NULL"; } else { var type = value.GetType(); if (type == UtilConstants.DateType) { var date = value.ObjToDate(); if (date < Convert.ToDateTime("1900-1-1")) { date = Convert.ToDateTime("1900-1-1"); } return "'" + date.ToString("yyyy-MM-dd HH:mm:ss.fff") + "'"; } else if (type == UtilConstants.ByteArrayType) { var bytesString = "0x" + BitConverter.ToString((byte[])value); return bytesString; } else if (type.IsEnum()) { return Convert.ToInt64(value); } else if (type == UtilConstants.BoolType) { return value.ObjToBool() ? "1" : "0"; } else if (type == UtilConstants.StringType || type == UtilConstants.ObjType) { return "N'" + value.ToString().ToSqlFilter() + "'"; } else { return "N'" + value.ToString() + "'"; } } } #endregion Methods } }