diff --git a/Src/Asp.NetCore2/SqlSugar/Abstract/InsertableProvider/InsertableHelper.cs b/Src/Asp.NetCore2/SqlSugar/Abstract/InsertableProvider/InsertableHelper.cs new file mode 100644 index 000000000..a22ac828f --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar/Abstract/InsertableProvider/InsertableHelper.cs @@ -0,0 +1,516 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace SqlSugar +{ + public partial class InsertableProvider : IInsertable where T : class, new() + { + #region Protected Methods + private string _ExecuteReturnBigIdentity() + { + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + AutoRemoveDataCache(); + string sql = InsertBuilder.ToSqlString(); + RestoreMapping(); + Before(sql); + return sql; + } + private string _ExecuteReturnIdentity() + { + InsertBuilder.IsReturnIdentity = true; + PreToSql(); + AutoRemoveDataCache(); + string sql = InsertBuilder.ToSqlString(); + RestoreMapping(); + Before(sql); + return sql; + } + + private string _ExecuteCommand() + { + if (InsertBuilder.DbColumnInfoList.HasValue()) + { + var pks = GetPrimaryKeys(); + foreach (var item in InsertBuilder.DbColumnInfoList) + { + var isPk = pks.Any(y => y.Equals(item.DbColumnName, StringComparison.CurrentCultureIgnoreCase)) || item.IsPrimarykey; + if (isPk && item.PropertyType == UtilConstants.GuidType && item.Value.ObjToString() == Guid.Empty.ToString()) + { + item.Value = Guid.NewGuid(); + if (InsertObjs.First().GetType().GetProperties().Any(it => it.Name == item.PropertyName)) + InsertObjs.First().GetType().GetProperties().First(it => it.Name == item.PropertyName).SetValue(InsertObjs.First(), item.Value, null); + } + } + } + InsertBuilder.IsReturnIdentity = false; + PreToSql(); + AutoRemoveDataCache(); + string sql = InsertBuilder.ToSqlString(); + RestoreMapping(); + Before(sql); + return sql; + } + private void AutoRemoveDataCache() + { + var moreSetts = this.Context.CurrentConnectionConfig.MoreSettings; + var extService = this.Context.CurrentConnectionConfig.ConfigureExternalServices; + if (moreSetts != null && moreSetts.IsAutoRemoveDataCache && extService != null && extService.DataInfoCacheService != null) + { + this.RemoveDataCache(); + } + } + protected virtual void PreToSql() + { + #region Identities + if (!IsOffIdentity) + { + List identities = GetIdentityKeys(); + if (identities != null && identities.Any()) + { + this.InsertBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.Where(it => + { + return !identities.Any(i => it.DbColumnName.Equals(i, StringComparison.CurrentCultureIgnoreCase)); + }).ToList(); + } + } + #endregion + + #region IgnoreColumns + if (this.Context.IgnoreColumns != null && this.Context.IgnoreColumns.Any()) + { + var currentIgnoreColumns = this.Context.IgnoreColumns.Where(it => it.EntityName == this.EntityInfo.EntityName).ToList(); + this.InsertBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.Where(it => + { + return !currentIgnoreColumns.Any(i => it.PropertyName.Equals(i.PropertyName, StringComparison.CurrentCulture)); + }).ToList(); + } + + if (this.Context.IgnoreInsertColumns != null && this.Context.IgnoreInsertColumns.Any()) + { + var currentIgnoreColumns = this.Context.IgnoreInsertColumns.Where(it => it.EntityName == this.EntityInfo.EntityName).ToList(); + this.InsertBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.Where(it => + { + return !currentIgnoreColumns.Any(i => it.PropertyName.Equals(i.PropertyName, StringComparison.CurrentCulture)); + }).ToList(); + } + #endregion + if (this.IsSingle) + { + foreach (var item in this.InsertBuilder.DbColumnInfoList) + { + if (this.InsertBuilder.Parameters == null) this.InsertBuilder.Parameters = new List(); + var paramters = new SugarParameter(this.SqlBuilder.SqlParameterKeyWord + item.DbColumnName, item.Value, item.PropertyType); + if (InsertBuilder.IsNoInsertNull && paramters.Value == null) + { + continue; + } + if (item.IsJson) + { + paramters.IsJson = true; + } + if (item.IsArray) + { + paramters.IsArray = true; + } + this.InsertBuilder.Parameters.Add(paramters); + } + } + } + internal void Init() + { + InsertBuilder.EntityInfo = this.EntityInfo; + Check.Exception(InsertObjs == null || InsertObjs.Count() == 0, "InsertObjs is null"); + int i = 0; + foreach (var item in InsertObjs) + { + List insertItem = new List(); + if (item is Dictionary) + { + SetInsertItemByDic(i, item, insertItem); + } + else + { + DataAop(item); + SetInsertItemByEntity(i, item, insertItem); + } + this.InsertBuilder.DbColumnInfoList.AddRange(insertItem); + ++i; + } + } + + private void DataAop(T item) + { + var dataEvent = this.Context.CurrentConnectionConfig.AopEvents?.DataExecuting; + if (dataEvent != null && item != null) + { + foreach (var columnInfo in this.EntityInfo.Columns) + { + dataEvent(columnInfo.PropertyInfo.GetValue(item, null), new DataFilterModel() { OperationType = DataFilterType.InsertByObject, EntityValue = item, EntityColumnInfo = columnInfo }); + } + } + } + + private void SetInsertItemByDic(int i, T item, List insertItem) + { + foreach (var column in item as Dictionary) + { + var columnInfo = new DbColumnInfo() + { + Value = column.Value, + DbColumnName = column.Key, + PropertyName = column.Key, + PropertyType = column.Value == null ? DBNull.Value.GetType() : UtilMethods.GetUnderType(column.Value.GetType()), + TableId = i + }; + if (columnInfo.PropertyType.IsEnum()) + { + if (this.Context.CurrentConnectionConfig.MoreSettings?.TableEnumIsString == true) + { + columnInfo.Value = columnInfo.Value.ToString(); + columnInfo.PropertyType = UtilConstants.StringType; + } + else + { + columnInfo.Value = Convert.ToInt64(columnInfo.Value); + } + } + insertItem.Add(columnInfo); + } + } + private void SetInsertItemByEntity(int i, T item, List insertItem) + { + if (item == null) + { + return; + } + foreach (var column in EntityInfo.Columns) + { + if (column.IsIgnore || column.IsOnlyIgnoreInsert) continue; + var isMapping = IsMappingColumns; + var columnInfo = new DbColumnInfo() + { + Value = PropertyCallAdapterProvider.GetInstance(column.PropertyName).InvokeGet(item), + DbColumnName = column.DbColumnName, + PropertyName = column.PropertyName, + PropertyType = UtilMethods.GetUnderType(column.PropertyInfo), + TableId = i + }; + if (column.DbColumnName == null) + { + column.DbColumnName = column.PropertyName; + } + if (isMapping) + { + columnInfo.DbColumnName = GetDbColumnName(column.PropertyName); + } + if (column.IsJson) + { + columnInfo.IsJson = true; + } + if (column.IsArray) + { + columnInfo.IsArray = true; + } + if (columnInfo.PropertyType.IsEnum() && columnInfo.Value != null) + { + if (this.Context.CurrentConnectionConfig.MoreSettings?.TableEnumIsString == true) + { + columnInfo.Value = columnInfo.Value.ToString(); + columnInfo.PropertyType = UtilConstants.StringType; + } + else + { + columnInfo.Value = Convert.ToInt64(columnInfo.Value); + } + } + if (column.IsJson && columnInfo.Value != null) + { + if (columnInfo.Value != null) + columnInfo.Value = this.Context.Utilities.SerializeObject(columnInfo.Value); + } + //var tranColumn=EntityInfo.Columns.FirstOrDefault(it => it.IsTranscoding && it.DbColumnName.Equals(column.DbColumnName, StringComparison.CurrentCultureIgnoreCase)); + if (column.IsTranscoding && columnInfo.Value.HasValue()) + { + columnInfo.Value = UtilMethods.EncodeBase64(columnInfo.Value.ToString()); + } + insertItem.Add(columnInfo); + } + } + + private string GetDbColumnName(string propertyName) + { + if (!IsMappingColumns) + { + return propertyName; + } + if (this.Context.MappingColumns.Any(it => it.EntityName.Equals(EntityInfo.EntityName, StringComparison.CurrentCultureIgnoreCase))) + { + this.MappingColumnList = this.Context.MappingColumns.Where(it => it.EntityName.Equals(EntityInfo.EntityName, StringComparison.CurrentCultureIgnoreCase)).ToList(); + } + if (MappingColumnList == null || !MappingColumnList.Any()) + { + return propertyName; + } + else + { + var mappInfo = this.MappingColumnList.FirstOrDefault(it => it.PropertyName.Equals(propertyName, StringComparison.CurrentCultureIgnoreCase)); + return mappInfo == null ? propertyName : mappInfo.DbColumnName; + } + } + + protected virtual List GetPrimaryKeys() + { + if (this.Context.IsSystemTablesConfig) + { + return this.Context.DbMaintenance.GetPrimaries(this.Context.EntityMaintenance.GetTableName(this.EntityInfo.EntityName)); + } + else + { + return this.EntityInfo.Columns.Where(it => it.IsPrimarykey).Select(it => it.DbColumnName).ToList(); + } + } + protected virtual List GetIdentityKeys() + { + if (this.Context.IsSystemTablesConfig) + { + return this.Context.DbMaintenance.GetIsIdentities(this.Context.EntityMaintenance.GetTableName(this.EntityInfo.EntityName)); + } + else + { + return this.EntityInfo.Columns.Where(it => { + + Check.Exception(it.IsIdentity && it.UnderType == typeof(string), "IsIdentity key can not be type of string"); + return it.IsIdentity; + + }).Select(it => it.DbColumnName).ToList(); + } + } + //private void TaskStart(Task result) + //{ + // if (this.Context.CurrentConnectionConfig.IsShardSameThread) + // { + // Check.Exception(true, "IsShardSameThread=true can't be used async method"); + // } + // result.Start(); + //} + protected void RestoreMapping() + { + if (IsAs) + { + this.Context.MappingTables = OldMappingTableList; + } + } + //protected IInsertable CopyInsertable() + //{ + // var asyncContext = this.Context.Utilities.CopyContext(true); + // asyncContext.CurrentConnectionConfig.IsAutoCloseConnection = true; + // asyncContext.IsAsyncMethod = true; + // var asyncInsertable = asyncContext.Insertable(this.InsertObjs); + // var asyncInsertableBuilder = asyncInsertable.InsertBuilder; + // asyncInsertableBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList; + // asyncInsertableBuilder.EntityInfo = this.InsertBuilder.EntityInfo; + // asyncInsertableBuilder.Parameters = this.InsertBuilder.Parameters; + // asyncInsertableBuilder.sql = this.InsertBuilder.sql; + // asyncInsertableBuilder.IsNoInsertNull = this.InsertBuilder.IsNoInsertNull; + // asyncInsertableBuilder.IsReturnIdentity = this.InsertBuilder.IsReturnIdentity; + // asyncInsertableBuilder.EntityInfo = this.InsertBuilder.EntityInfo; + // asyncInsertableBuilder.TableWithString = this.InsertBuilder.TableWithString; + // if (this.RemoveCacheFunc != null) + // { + // asyncInsertable.RemoveDataCache(); + // } + // return asyncInsertable; + //} + + protected void After(string sql, long? result) + { + if (this.IsEnableDiffLogEvent) + { + var isDisableMasterSlaveSeparation = this.Ado.IsDisableMasterSlaveSeparation; + this.Ado.IsDisableMasterSlaveSeparation = true; + var parameters = InsertBuilder.Parameters; + if (parameters == null) + parameters = new List(); + diffModel.AfterData = GetDiffTable(sql, result); + diffModel.Time = this.Context.Ado.SqlExecutionTime; + if (this.Context.CurrentConnectionConfig.AopEvents.OnDiffLogEvent != null) + this.Context.CurrentConnectionConfig.AopEvents.OnDiffLogEvent(diffModel); + this.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation; + } + if (this.RemoveCacheFunc != null) + { + this.RemoveCacheFunc(); + } + } + protected void Before(string sql) + { + if (this.IsEnableDiffLogEvent) + { + var isDisableMasterSlaveSeparation = this.Ado.IsDisableMasterSlaveSeparation; + this.Ado.IsDisableMasterSlaveSeparation = true; + var parameters = InsertBuilder.Parameters; + if (parameters == null) + parameters = new List(); + diffModel.BeforeData = null; + diffModel.Sql = sql; + diffModel.Parameters = parameters.ToArray(); + this.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation; + } + } + private List GetDiffTable(string sql, long? identity) + { + + if (GetIdentityKeys().HasValue() && this.InsertObjs.Count() > 1) + { + return GetDiffTableByEntity(); + } + else if (GetIdentityKeys().IsNullOrEmpty()) + { + return GetDiffTableByEntity(); + } + else + { + return GetDiffTableBySql(identity); + } + + } + + private List GetDiffTableByEntity() + { + List parameters = new List(); + List result = new List(); + var dt2 = this.Context.Utilities.ListToDataTable(this.InsertObjs.ToList()); + foreach (DataRow row in dt2.Rows) + { + DiffLogTableInfo item = new DiffLogTableInfo(); + item.TableDescription = this.EntityInfo.TableDescription; + item.TableName = this.EntityInfo.DbTableName; + item.Columns = new List(); + foreach (DataColumn col in dt2.Columns) + { + var sugarColumn = this.EntityInfo.Columns.Where(it => it.DbColumnName != null).FirstOrDefault(it => + it.DbColumnName.Equals(col.ColumnName, StringComparison.CurrentCultureIgnoreCase)); + DiffLogColumnInfo addItem = new DiffLogColumnInfo(); + addItem.Value = row[col.ColumnName]; + addItem.ColumnName = col.ColumnName; + addItem.IsPrimaryKey = sugarColumn?.IsPrimarykey ?? false; + addItem.ColumnDescription = sugarColumn?.ColumnDescription; + item.Columns.Add(addItem); + } + result.Add(item); + } + return result; + } + + private List GetDiffTableBySql(long? identity) + { + List parameters = new List(); + List result = new List(); + var whereSql = string.Empty; + List cons = new List(); + if (identity != null && identity > 0 && GetIdentityKeys().HasValue()) + { + var fieldName = GetIdentityKeys().Last(); + + if (this.Context.CurrentConnectionConfig.DbType == DbType.PostgreSQL) + { + var fieldObjectType = this.EntityInfo.Columns.FirstOrDefault(x => x.DbColumnName == fieldName) + .PropertyInfo.PropertyType; + cons.Add(new ConditionalModel() + { + ConditionalType = ConditionalType.Equal, + FieldName = fieldName, + FieldValue = identity.ToString(), + FieldValueConvertFunc = it => UtilMethods.ChangeType2(it, fieldObjectType) + }); + } + else + cons.Add(new ConditionalModel() { ConditionalType = ConditionalType.Equal, FieldName = fieldName, FieldValue = identity.ToString() }); + } + else + { + foreach (var item in this.EntityInfo.Columns.Where(it => it.IsIgnore == false && GetPrimaryKeys().Any(pk => pk.Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase)))) + { + var fielddName = item.DbColumnName; + var filedObject = this.EntityInfo.Columns.FirstOrDefault(it => it.PropertyName == item.PropertyName).PropertyInfo.GetValue(this.InsertObjs.Last(), null); + var fieldValue = filedObject.ObjToString(); + if (filedObject != null && filedObject.GetType() != typeof(string) && this.Context.CurrentConnectionConfig.DbType == DbType.PostgreSQL) + { + cons.Add(new ConditionalModel() { ConditionalType = ConditionalType.Equal, FieldName = fielddName, FieldValue = fieldValue, FieldValueConvertFunc = it => UtilMethods.ChangeType2(it, filedObject.GetType()) }); + } + else + { + cons.Add(new ConditionalModel() { ConditionalType = ConditionalType.Equal, FieldName = fielddName, FieldValue = fieldValue }); + } + } + } + Check.Exception(cons.IsNullOrEmpty(), "Insertable.EnableDiffLogEvent need primary key"); + var sqlable = this.SqlBuilder.ConditionalModelToSql(cons); + whereSql = sqlable.Key; + parameters.AddRange(sqlable.Value); + var dt = this.Context.Queryable().Where(whereSql).AddParameters(parameters).ToDataTable(); + if (dt.Rows != null && dt.Rows.Count > 0) + { + foreach (DataRow row in dt.Rows) + { + DiffLogTableInfo item = new DiffLogTableInfo(); + item.TableDescription = this.EntityInfo.TableDescription; + item.TableName = this.EntityInfo.DbTableName; + item.Columns = new List(); + foreach (DataColumn col in dt.Columns) + { + var sugarColumn = this.EntityInfo.Columns.Where(it => it.DbColumnName != null).First(it => + it.DbColumnName.Equals(col.ColumnName, StringComparison.CurrentCultureIgnoreCase)); + DiffLogColumnInfo addItem = new DiffLogColumnInfo(); + addItem.Value = row[col.ColumnName]; + addItem.ColumnName = col.ColumnName; + addItem.IsPrimaryKey = sugarColumn.IsPrimarykey; + addItem.ColumnDescription = sugarColumn.ColumnDescription; + item.Columns.Add(addItem); + } + result.Add(item); + } + return result; + } + else + { + DiffLogTableInfo diffTable = new DiffLogTableInfo(); + diffTable.TableName = this.EntityInfo.DbTableName; + diffTable.TableDescription = this.EntityInfo.TableDescription; + diffTable.Columns = this.EntityInfo.Columns.Where(it => it.IsIgnore == false).Select(it => new DiffLogColumnInfo() + { + ColumnDescription = it.ColumnDescription, + ColumnName = it.DbColumnName, + Value = it.PropertyInfo.GetValue(this.InsertObjs.Last(), null), + IsPrimaryKey = it.IsPrimarykey + }).ToList(); + return new List() { diffTable }; + } + } + + public IInsertable CallEntityMethod(Expression> method) + { + if (this.InsertObjs.HasValue()) + { + var oldColumns = this.InsertBuilder.DbColumnInfoList.Select(it => it.PropertyName).ToList(); + var expression = (LambdaExpression.Lambda(method).Body as LambdaExpression).Body; + Check.Exception(!(expression is MethodCallExpression), method.ToString() + " is not method"); + var callExpresion = expression as MethodCallExpression; + UtilMethods.DataInoveByExpresson(this.InsertObjs, callExpresion); + this.InsertBuilder.DbColumnInfoList = new List(); + Init(); + this.InsertBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.Where(it => oldColumns.Contains(it.PropertyName)).ToList(); + } + return this; + } + + #endregion + } +} diff --git a/Src/Asp.NetCore2/SqlSugar/Abstract/InsertableProvider/InsertableProvider.cs b/Src/Asp.NetCore2/SqlSugar/Abstract/InsertableProvider/InsertableProvider.cs index 5a308331e..383f84c64 100644 --- a/Src/Asp.NetCore2/SqlSugar/Abstract/InsertableProvider/InsertableProvider.cs +++ b/Src/Asp.NetCore2/SqlSugar/Abstract/InsertableProvider/InsertableProvider.cs @@ -9,7 +9,7 @@ using System.Threading.Tasks; namespace SqlSugar { - public class InsertableProvider : IInsertable where T : class, new() + public partial class InsertableProvider : IInsertable where T : class, new() { public SqlSugarProvider Context { get; set; } public IAdo Ado { get { return Context.Ado; } } @@ -518,501 +518,5 @@ namespace SqlSugar #endregion - #region Protected Methods - private string _ExecuteReturnBigIdentity() - { - InsertBuilder.IsReturnIdentity = true; - PreToSql(); - AutoRemoveDataCache(); - string sql = InsertBuilder.ToSqlString(); - RestoreMapping(); - Before(sql); - return sql; - } - private string _ExecuteReturnIdentity() - { - InsertBuilder.IsReturnIdentity = true; - PreToSql(); - AutoRemoveDataCache(); - string sql = InsertBuilder.ToSqlString(); - RestoreMapping(); - Before(sql); - return sql; - } - - private string _ExecuteCommand() - { - if (InsertBuilder.DbColumnInfoList.HasValue()) - { - var pks = GetPrimaryKeys(); - foreach (var item in InsertBuilder.DbColumnInfoList) - { - var isPk = pks.Any(y => y.Equals(item.DbColumnName, StringComparison.CurrentCultureIgnoreCase)) || item.IsPrimarykey; - if (isPk && item.PropertyType == UtilConstants.GuidType && item.Value.ObjToString() == Guid.Empty.ToString()) - { - item.Value = Guid.NewGuid(); - if (InsertObjs.First().GetType().GetProperties().Any(it => it.Name == item.PropertyName)) - InsertObjs.First().GetType().GetProperties().First(it => it.Name == item.PropertyName).SetValue(InsertObjs.First(), item.Value, null); - } - } - } - InsertBuilder.IsReturnIdentity = false; - PreToSql(); - AutoRemoveDataCache(); - string sql = InsertBuilder.ToSqlString(); - RestoreMapping(); - Before(sql); - return sql; - } - private void AutoRemoveDataCache() - { - var moreSetts = this.Context.CurrentConnectionConfig.MoreSettings; - var extService = this.Context.CurrentConnectionConfig.ConfigureExternalServices; - if (moreSetts != null && moreSetts.IsAutoRemoveDataCache && extService != null && extService.DataInfoCacheService != null) - { - this.RemoveDataCache(); - } - } - protected virtual void PreToSql() - { - #region Identities - if (!IsOffIdentity) - { - List identities = GetIdentityKeys(); - if (identities != null && identities.Any()) - { - this.InsertBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.Where(it => - { - return !identities.Any(i => it.DbColumnName.Equals(i, StringComparison.CurrentCultureIgnoreCase)); - }).ToList(); - } - } - #endregion - - #region IgnoreColumns - if (this.Context.IgnoreColumns != null && this.Context.IgnoreColumns.Any()) - { - var currentIgnoreColumns = this.Context.IgnoreColumns.Where(it => it.EntityName == this.EntityInfo.EntityName).ToList(); - this.InsertBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.Where(it => - { - return !currentIgnoreColumns.Any(i => it.PropertyName.Equals(i.PropertyName, StringComparison.CurrentCulture)); - }).ToList(); - } - - if (this.Context.IgnoreInsertColumns != null && this.Context.IgnoreInsertColumns.Any()) - { - var currentIgnoreColumns = this.Context.IgnoreInsertColumns.Where(it => it.EntityName == this.EntityInfo.EntityName).ToList(); - this.InsertBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.Where(it => - { - return !currentIgnoreColumns.Any(i => it.PropertyName.Equals(i.PropertyName, StringComparison.CurrentCulture)); - }).ToList(); - } - #endregion - if (this.IsSingle) - { - foreach (var item in this.InsertBuilder.DbColumnInfoList) - { - if (this.InsertBuilder.Parameters == null) this.InsertBuilder.Parameters = new List(); - var paramters = new SugarParameter(this.SqlBuilder.SqlParameterKeyWord + item.DbColumnName, item.Value, item.PropertyType); - if (InsertBuilder.IsNoInsertNull && paramters.Value == null) - { - continue; - } - if (item.IsJson) - { - paramters.IsJson = true; - } - if (item.IsArray) - { - paramters.IsArray = true; - } - this.InsertBuilder.Parameters.Add(paramters); - } - } - } - internal void Init() - { - InsertBuilder.EntityInfo = this.EntityInfo; - Check.Exception(InsertObjs == null || InsertObjs.Count() == 0, "InsertObjs is null"); - int i = 0; - foreach (var item in InsertObjs) - { - List insertItem = new List(); - if (item is Dictionary) - { - SetInsertItemByDic(i, item, insertItem); - } - else - { - DataAop(item); - SetInsertItemByEntity(i, item, insertItem); - } - this.InsertBuilder.DbColumnInfoList.AddRange(insertItem); - ++i; - } - } - - private void DataAop(T item) - { - var dataEvent=this.Context.CurrentConnectionConfig.AopEvents?.DataExecuting; - if (dataEvent != null && item != null) - { - foreach (var columnInfo in this.EntityInfo.Columns) - { - dataEvent(columnInfo.PropertyInfo.GetValue(item, null), new DataFilterModel() { OperationType = DataFilterType.InsertByObject,EntityValue=item, EntityColumnInfo = columnInfo }); - } - } - } - - private void SetInsertItemByDic(int i, T item, List insertItem) - { - foreach (var column in item as Dictionary) - { - var columnInfo = new DbColumnInfo() - { - Value = column.Value, - DbColumnName = column.Key, - PropertyName = column.Key, - PropertyType = column.Value == null ? DBNull.Value.GetType() : UtilMethods.GetUnderType(column.Value.GetType()), - TableId = i - }; - if (columnInfo.PropertyType.IsEnum()) - { - if (this.Context.CurrentConnectionConfig.MoreSettings?.TableEnumIsString == true) - { - columnInfo.Value = columnInfo.Value.ToString(); - columnInfo.PropertyType = UtilConstants.StringType; - } - else - { - columnInfo.Value = Convert.ToInt64(columnInfo.Value); - } - } - insertItem.Add(columnInfo); - } - } - private void SetInsertItemByEntity(int i, T item, List insertItem) - { - if (item == null) - { - return; - } - foreach (var column in EntityInfo.Columns) - { - if (column.IsIgnore || column.IsOnlyIgnoreInsert) continue; - var isMapping = IsMappingColumns; - var columnInfo = new DbColumnInfo() - { - Value = PropertyCallAdapterProvider.GetInstance(column.PropertyName).InvokeGet(item), - DbColumnName = column.DbColumnName, - PropertyName = column.PropertyName, - PropertyType = UtilMethods.GetUnderType(column.PropertyInfo), - TableId = i - }; - if (column.DbColumnName == null) - { - column.DbColumnName = column.PropertyName; - } - if (isMapping) - { - columnInfo.DbColumnName = GetDbColumnName(column.PropertyName); - } - if (column.IsJson) - { - columnInfo.IsJson = true; - } - if (column.IsArray) - { - columnInfo.IsArray = true; - } - if (columnInfo.PropertyType.IsEnum()&& columnInfo.Value!=null) - { - if (this.Context.CurrentConnectionConfig.MoreSettings?.TableEnumIsString == true) - { - columnInfo.Value = columnInfo.Value.ToString(); - columnInfo.PropertyType = UtilConstants.StringType; - } - else - { - columnInfo.Value = Convert.ToInt64(columnInfo.Value); - } - } - if (column.IsJson&& columnInfo.Value!=null) - { - if(columnInfo.Value!=null) - columnInfo.Value = this.Context.Utilities.SerializeObject(columnInfo.Value); - } - //var tranColumn=EntityInfo.Columns.FirstOrDefault(it => it.IsTranscoding && it.DbColumnName.Equals(column.DbColumnName, StringComparison.CurrentCultureIgnoreCase)); - if (column.IsTranscoding&&columnInfo.Value.HasValue()) { - columnInfo.Value = UtilMethods.EncodeBase64(columnInfo.Value.ToString()); - } - insertItem.Add(columnInfo); - } - } - - private string GetDbColumnName(string propertyName) - { - if (!IsMappingColumns) - { - return propertyName; - } - if (this.Context.MappingColumns.Any(it => it.EntityName.Equals(EntityInfo.EntityName, StringComparison.CurrentCultureIgnoreCase))) - { - this.MappingColumnList = this.Context.MappingColumns.Where(it => it.EntityName.Equals(EntityInfo.EntityName, StringComparison.CurrentCultureIgnoreCase)).ToList(); - } - if (MappingColumnList == null || !MappingColumnList.Any()) - { - return propertyName; - } - else - { - var mappInfo = this.MappingColumnList.FirstOrDefault(it => it.PropertyName.Equals(propertyName, StringComparison.CurrentCultureIgnoreCase)); - return mappInfo == null ? propertyName : mappInfo.DbColumnName; - } - } - - protected virtual List GetPrimaryKeys() - { - if (this.Context.IsSystemTablesConfig) - { - return this.Context.DbMaintenance.GetPrimaries(this.Context.EntityMaintenance.GetTableName(this.EntityInfo.EntityName)); - } - else - { - return this.EntityInfo.Columns.Where(it => it.IsPrimarykey).Select(it => it.DbColumnName).ToList(); - } - } - protected virtual List GetIdentityKeys() - { - if (this.Context.IsSystemTablesConfig) - { - return this.Context.DbMaintenance.GetIsIdentities(this.Context.EntityMaintenance.GetTableName(this.EntityInfo.EntityName)); - } - else - { - return this.EntityInfo.Columns.Where(it => { - - Check.Exception(it.IsIdentity&&it.UnderType == typeof(string), "IsIdentity key can not be type of string"); - return it.IsIdentity; - - }).Select(it => it.DbColumnName).ToList(); - } - } - //private void TaskStart(Task result) - //{ - // if (this.Context.CurrentConnectionConfig.IsShardSameThread) - // { - // Check.Exception(true, "IsShardSameThread=true can't be used async method"); - // } - // result.Start(); - //} - protected void RestoreMapping() - { - if (IsAs) - { - this.Context.MappingTables = OldMappingTableList; - } - } - //protected IInsertable CopyInsertable() - //{ - // var asyncContext = this.Context.Utilities.CopyContext(true); - // asyncContext.CurrentConnectionConfig.IsAutoCloseConnection = true; - // asyncContext.IsAsyncMethod = true; - // var asyncInsertable = asyncContext.Insertable(this.InsertObjs); - // var asyncInsertableBuilder = asyncInsertable.InsertBuilder; - // asyncInsertableBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList; - // asyncInsertableBuilder.EntityInfo = this.InsertBuilder.EntityInfo; - // asyncInsertableBuilder.Parameters = this.InsertBuilder.Parameters; - // asyncInsertableBuilder.sql = this.InsertBuilder.sql; - // asyncInsertableBuilder.IsNoInsertNull = this.InsertBuilder.IsNoInsertNull; - // asyncInsertableBuilder.IsReturnIdentity = this.InsertBuilder.IsReturnIdentity; - // asyncInsertableBuilder.EntityInfo = this.InsertBuilder.EntityInfo; - // asyncInsertableBuilder.TableWithString = this.InsertBuilder.TableWithString; - // if (this.RemoveCacheFunc != null) - // { - // asyncInsertable.RemoveDataCache(); - // } - // return asyncInsertable; - //} - - protected void After(string sql, long? result) - { - if (this.IsEnableDiffLogEvent) - { - var isDisableMasterSlaveSeparation = this.Ado.IsDisableMasterSlaveSeparation; - this.Ado.IsDisableMasterSlaveSeparation = true; - var parameters = InsertBuilder.Parameters; - if (parameters == null) - parameters = new List(); - diffModel.AfterData = GetDiffTable(sql, result); - diffModel.Time = this.Context.Ado.SqlExecutionTime; - if (this.Context.CurrentConnectionConfig.AopEvents.OnDiffLogEvent != null) - this.Context.CurrentConnectionConfig.AopEvents.OnDiffLogEvent(diffModel); - this.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation; - } - if (this.RemoveCacheFunc != null) - { - this.RemoveCacheFunc(); - } - } - protected void Before(string sql) - { - if (this.IsEnableDiffLogEvent) - { - var isDisableMasterSlaveSeparation = this.Ado.IsDisableMasterSlaveSeparation; - this.Ado.IsDisableMasterSlaveSeparation = true; - var parameters = InsertBuilder.Parameters; - if (parameters == null) - parameters = new List(); - diffModel.BeforeData = null; - diffModel.Sql = sql; - diffModel.Parameters = parameters.ToArray(); - this.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation; - } - } - private List GetDiffTable(string sql, long? identity) - { - - if (GetIdentityKeys().HasValue() && this.InsertObjs.Count() > 1) - { - return GetDiffTableByEntity(); - } - else if (GetIdentityKeys().IsNullOrEmpty()) - { - return GetDiffTableByEntity(); - } - else - { - return GetDiffTableBySql(identity); - } - - } - - private List GetDiffTableByEntity() - { - List parameters = new List(); - List result = new List(); - var dt2 = this.Context.Utilities.ListToDataTable(this.InsertObjs.ToList()); - foreach (DataRow row in dt2.Rows) - { - DiffLogTableInfo item = new DiffLogTableInfo(); - item.TableDescription = this.EntityInfo.TableDescription; - item.TableName = this.EntityInfo.DbTableName; - item.Columns = new List(); - foreach (DataColumn col in dt2.Columns) - { - var sugarColumn = this.EntityInfo.Columns.Where(it => it.DbColumnName != null).FirstOrDefault(it => - it.DbColumnName.Equals(col.ColumnName, StringComparison.CurrentCultureIgnoreCase)); - DiffLogColumnInfo addItem = new DiffLogColumnInfo(); - addItem.Value = row[col.ColumnName]; - addItem.ColumnName = col.ColumnName; - addItem.IsPrimaryKey = sugarColumn?.IsPrimarykey ?? false; - addItem.ColumnDescription = sugarColumn?.ColumnDescription; - item.Columns.Add(addItem); - } - result.Add(item); - } - return result; - } - - private List GetDiffTableBySql(long? identity) - { - List parameters = new List(); - List result = new List(); - var whereSql = string.Empty; - List cons = new List(); - if (identity != null && identity > 0 && GetIdentityKeys().HasValue()) - { - var fieldName = GetIdentityKeys().Last(); - - if (this.Context.CurrentConnectionConfig.DbType == DbType.PostgreSQL) - { - var fieldObjectType = this.EntityInfo.Columns.FirstOrDefault(x => x.DbColumnName == fieldName) - .PropertyInfo.PropertyType; - cons.Add(new ConditionalModel() { ConditionalType = ConditionalType.Equal, FieldName = fieldName, FieldValue = identity.ToString(), - FieldValueConvertFunc = it => UtilMethods.ChangeType2(it, fieldObjectType) }); - } - else - cons.Add(new ConditionalModel() { ConditionalType = ConditionalType.Equal, FieldName = fieldName, FieldValue = identity.ToString() }); - } - else - { - foreach (var item in this.EntityInfo.Columns.Where(it => it.IsIgnore == false && GetPrimaryKeys().Any(pk => pk.Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase)))) - { - var fielddName = item.DbColumnName; - var filedObject = this.EntityInfo.Columns.FirstOrDefault(it => it.PropertyName == item.PropertyName).PropertyInfo.GetValue(this.InsertObjs.Last(), null); - var fieldValue = filedObject.ObjToString(); - if (filedObject != null && filedObject.GetType() != typeof(string) && this.Context.CurrentConnectionConfig.DbType == DbType.PostgreSQL) - { - cons.Add(new ConditionalModel() { ConditionalType = ConditionalType.Equal, FieldName = fielddName, FieldValue = fieldValue, FieldValueConvertFunc = it => UtilMethods.ChangeType2(it, filedObject.GetType()) }); - } - else - { - cons.Add(new ConditionalModel() { ConditionalType = ConditionalType.Equal, FieldName = fielddName, FieldValue = fieldValue }); - } - } - } - Check.Exception(cons.IsNullOrEmpty(), "Insertable.EnableDiffLogEvent need primary key"); - var sqlable = this.SqlBuilder.ConditionalModelToSql(cons); - whereSql = sqlable.Key; - parameters.AddRange(sqlable.Value); - var dt = this.Context.Queryable().Where(whereSql).AddParameters(parameters).ToDataTable(); - if (dt.Rows != null && dt.Rows.Count > 0) - { - foreach (DataRow row in dt.Rows) - { - DiffLogTableInfo item = new DiffLogTableInfo(); - item.TableDescription = this.EntityInfo.TableDescription; - item.TableName = this.EntityInfo.DbTableName; - item.Columns = new List(); - foreach (DataColumn col in dt.Columns) - { - var sugarColumn = this.EntityInfo.Columns.Where(it => it.DbColumnName != null).First(it => - it.DbColumnName.Equals(col.ColumnName, StringComparison.CurrentCultureIgnoreCase)); - DiffLogColumnInfo addItem = new DiffLogColumnInfo(); - addItem.Value = row[col.ColumnName]; - addItem.ColumnName = col.ColumnName; - addItem.IsPrimaryKey = sugarColumn.IsPrimarykey; - addItem.ColumnDescription = sugarColumn.ColumnDescription; - item.Columns.Add(addItem); - } - result.Add(item); - } - return result; - } - else - { - DiffLogTableInfo diffTable = new DiffLogTableInfo(); - diffTable.TableName = this.EntityInfo.DbTableName; - diffTable.TableDescription = this.EntityInfo.TableDescription; - diffTable.Columns = this.EntityInfo.Columns.Where(it => it.IsIgnore == false).Select(it => new DiffLogColumnInfo() - { - ColumnDescription = it.ColumnDescription, - ColumnName = it.DbColumnName, - Value = it.PropertyInfo.GetValue(this.InsertObjs.Last(), null), - IsPrimaryKey = it.IsPrimarykey - }).ToList(); - return new List() { diffTable }; - } - } - - public IInsertable CallEntityMethod(Expression> method) - { - if (this.InsertObjs.HasValue()) - { - var oldColumns = this.InsertBuilder.DbColumnInfoList.Select(it => it.PropertyName).ToList(); - var expression = (LambdaExpression.Lambda(method).Body as LambdaExpression).Body; - Check.Exception(!(expression is MethodCallExpression), method.ToString() + " is not method"); - var callExpresion = expression as MethodCallExpression; - UtilMethods.DataInoveByExpresson(this.InsertObjs,callExpresion); - this.InsertBuilder.DbColumnInfoList = new List(); - Init(); - this.InsertBuilder.DbColumnInfoList = this.InsertBuilder.DbColumnInfoList.Where(it => oldColumns.Contains(it.PropertyName)).ToList(); - } - return this; - } - - #endregion - } } diff --git a/Src/Asp.NetCore2/SqlSugar/Abstract/UpdateProvider/UpdateableHelper.cs b/Src/Asp.NetCore2/SqlSugar/Abstract/UpdateProvider/UpdateableHelper.cs new file mode 100644 index 000000000..86edea5ba --- /dev/null +++ b/Src/Asp.NetCore2/SqlSugar/Abstract/UpdateProvider/UpdateableHelper.cs @@ -0,0 +1,505 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace SqlSugar +{ + public partial class UpdateableProvider : IUpdateable where T : class, new() + { + + private bool UpdateObjectNotWhere() + { + return this.Context.CurrentConnectionConfig.DbType != DbType.MySql + && this.Context.CurrentConnectionConfig.DbType != DbType.MySqlConnector + && this.Context.CurrentConnectionConfig.DbType != DbType.SqlServer; + } + + private void AppendSets() + { + if (SetColumnsIndex > 0) + { + var keys = UpdateBuilder.SetValues.Select(it => SqlBuilder.GetNoTranslationColumnName(it.Key.ToLower())).ToList(); + var addKeys = keys.Where(k => !this.UpdateBuilder.DbColumnInfoList.Any(it => it.PropertyName.ToLower() == k || it.DbColumnName.ToLower() == k)).ToList(); + var addItems = this.EntityInfo.Columns.Where(it => !GetPrimaryKeys().Any(p => p.ToLower() == it.PropertyName?.ToLower() || p.ToLower() == it.DbColumnName?.ToLower()) && addKeys.Any(k => it.PropertyName?.ToLower() == k || it.DbColumnName?.ToLower() == k)).ToList(); + this.UpdateBuilder.DbColumnInfoList.AddRange(addItems.Select(it => new DbColumnInfo() { PropertyName = it.PropertyName, DbColumnName = it.DbColumnName })); + } + SetColumnsIndex++; + } + private string _ExecuteCommand() + { + PreToSql(); + AutoRemoveDataCache(); + Check.Exception(UpdateBuilder.WhereValues.IsNullOrEmpty() && GetPrimaryKeys().IsNullOrEmpty(), "You cannot have no primary key and no conditions"); + string sql = UpdateBuilder.ToSqlString(); + ValidateVersion(); + RestoreMapping(); + Before(sql); + return sql; + } + + private void _WhereColumn(string columnName) + { + var columnInfos = columns.Where(it => it.DbColumnName.Equals(columnName, StringComparison.OrdinalIgnoreCase) || it.PropertyName.Equals(columnName, StringComparison.OrdinalIgnoreCase)).ToList(); + if (!this.UpdateBuilder.DbColumnInfoList.Any(y => y.DbColumnName == columnInfos.First().DbColumnName)) + { + this.UpdateBuilder.DbColumnInfoList.AddRange(columnInfos); + } + } + + private void AutoRemoveDataCache() + { + var moreSetts = this.Context.CurrentConnectionConfig.MoreSettings; + var extService = this.Context.CurrentConnectionConfig.ConfigureExternalServices; + if (moreSetts != null && moreSetts.IsAutoRemoveDataCache && extService != null && extService.DataInfoCacheService != null) + { + this.RemoveDataCache(); + } + } + internal void Init() + { + this.UpdateBuilder.TableName = EntityInfo.EntityName; + if (IsMappingTable) + { + var mappingInfo = this.Context.MappingTables.SingleOrDefault(it => it.EntityName == EntityInfo.EntityName); + if (mappingInfo != null) + { + this.UpdateBuilder.TableName = mappingInfo.DbTableName; + } + } + //Check.Exception(UpdateObjs == null || UpdateObjs.Count() == 0, "UpdateObjs is null"); + int i = 0; + foreach (var item in UpdateObjs) + { + List updateItem = new List(); + var isDic = item is Dictionary; + if (isDic) + { + SetUpdateItemByDic(i, item, updateItem); + } + else + { + DataAop(item); + SetUpdateItemByEntity(i, item, updateItem); + } + ++i; + } + this.columns = this.UpdateBuilder.DbColumnInfoList; + + var ignoreColumns = EntityInfo.Columns.Where(it => it.IsOnlyIgnoreUpdate).ToList(); + if (ignoreColumns != null && ignoreColumns.Any()) + { + this.IgnoreColumns(ignoreColumns.Select(it => it.PropertyName).ToArray()); + } + } + + private void DataAop(T item) + { + var dataEvent = this.Context.CurrentConnectionConfig.AopEvents?.DataExecuting; + if (dataEvent != null && item != null) + { + foreach (var columnInfo in this.EntityInfo.Columns) + { + dataEvent(columnInfo.PropertyInfo.GetValue(item, null), new DataFilterModel() { OperationType = DataFilterType.UpdateByObject, EntityValue = item, EntityColumnInfo = columnInfo }); + } + } + } + + private void CheckTranscodeing(bool checkIsJson = true) + { + if (this.EntityInfo.Columns.Any(it => it.IsTranscoding)) + { + Check.Exception(true, ErrorMessage.GetThrowMessage("UpdateColumns no support IsTranscoding", "SetColumns方式更新不支持IsTranscoding,你可以使用db.Updateable(实体)的方式更新")); + } + if (checkIsJson && this.EntityInfo.Columns.Any(it => it.IsJson)) + { + Check.Exception(true, ErrorMessage.GetThrowMessage("UpdateColumns no support IsJson", "SetColumns方式更新不支持IsJson,你可以使用db.Updateable(实体)的方式更新")); + } + if (this.EntityInfo.Columns.Any(it => it.IsArray)) + { + Check.Exception(true, ErrorMessage.GetThrowMessage("UpdateColumns no support IsArray", "SetColumns方式更新不支持IsArray,你可以使用db.Updateable(实体)的方式更新")); + } + } + private void SetUpdateItemByDic(int i, T item, List updateItem) + { + foreach (var column in item as Dictionary) + { + var columnInfo = new DbColumnInfo() + { + Value = column.Value, + DbColumnName = column.Key, + PropertyName = column.Key, + PropertyType = column.Value == null ? DBNull.Value.GetType() : UtilMethods.GetUnderType(column.Value.GetType()), + TableId = i + }; + if (columnInfo.PropertyType.IsEnum()) + { + if (this.Context.CurrentConnectionConfig.MoreSettings?.TableEnumIsString == true) + { + columnInfo.PropertyType = UtilConstants.StringType; + columnInfo.Value = columnInfo.Value.ToString(); + } + else + { + columnInfo.Value = Convert.ToInt64(columnInfo.Value); + } + } + updateItem.Add(columnInfo); + } + this.UpdateBuilder.DbColumnInfoList.AddRange(updateItem); + } + private void SetUpdateItemByEntity(int i, T item, List updateItem) + { + foreach (var column in EntityInfo.Columns) + { + if (column.IsIgnore) continue; + var columnInfo = new DbColumnInfo() + { + Value = column.PropertyInfo.GetValue(item, null), + DbColumnName = GetDbColumnName(column.PropertyName), + PropertyName = column.PropertyName, + PropertyType = UtilMethods.GetUnderType(column.PropertyInfo), + TableId = i + }; + if (columnInfo.PropertyType.IsEnum() && columnInfo.Value != null) + { + if (this.Context.CurrentConnectionConfig.MoreSettings?.TableEnumIsString == true) + { + columnInfo.PropertyType = UtilConstants.StringType; + columnInfo.Value = columnInfo.Value.ToString(); + } + else + { + columnInfo.Value = Convert.ToInt64(columnInfo.Value); + } + } + if (column.IsJson) + { + columnInfo.IsJson = true; + if (columnInfo.Value != null) + columnInfo.Value = this.Context.Utilities.SerializeObject(columnInfo.Value); + } + if (column.IsArray) + { + columnInfo.IsArray = true; + } + var tranColumn = EntityInfo.Columns.FirstOrDefault(it => it.IsTranscoding && it.DbColumnName.Equals(column.DbColumnName, StringComparison.CurrentCultureIgnoreCase)); + if (tranColumn != null && columnInfo.Value.HasValue()) + { + columnInfo.Value = UtilMethods.EncodeBase64(columnInfo.Value.ToString()); + } + updateItem.Add(columnInfo); + } + this.UpdateBuilder.DbColumnInfoList.AddRange(updateItem); + } + + private void PreToSql() + { + + UpdateBuilder.PrimaryKeys = GetPrimaryKeys(); + if (this.IsWhereColumns) + { + foreach (var pkName in UpdateBuilder.PrimaryKeys) + { + if (WhereColumnList != null && WhereColumnList.Count() > 0) + { + continue; + } + var isContains = this.UpdateBuilder.DbColumnInfoList.Select(it => it.DbColumnName.ToLower()).Contains(pkName.ToLower()); + Check.Exception(isContains == false, "Use UpdateColumns().WhereColumn() ,UpdateColumns need {0}", pkName); + } + } + #region IgnoreColumns + if (this.Context.IgnoreColumns != null && this.Context.IgnoreColumns.Any()) + { + var currentIgnoreColumns = this.Context.IgnoreColumns.Where(it => it.EntityName == this.EntityInfo.EntityName).ToList(); + this.UpdateBuilder.DbColumnInfoList = this.UpdateBuilder.DbColumnInfoList.Where(it => + { + return !currentIgnoreColumns.Any(i => it.PropertyName.Equals(i.PropertyName, StringComparison.CurrentCulture)); + }).ToList(); + } + #endregion + if (this.IsSingle) + { + foreach (var item in this.UpdateBuilder.DbColumnInfoList) + { + if (this.UpdateBuilder.Parameters == null) this.UpdateBuilder.Parameters = new List(); + if (this.UpdateBuilder.SetValues.Any(it => this.SqlBuilder.GetNoTranslationColumnName(it.Key) == item.PropertyName)) + { + continue; + } + var parameter = new SugarParameter(this.SqlBuilder.SqlParameterKeyWord + item.DbColumnName, item.Value, item.PropertyType); + if (item.IsJson) + { + parameter.IsJson = true; + } + if (item.IsArray) + { + parameter.IsArray = true; + } + this.UpdateBuilder.Parameters.Add(parameter); + } + } + + #region Identities + List identities = GetIdentityKeys(); + if (identities != null && identities.Any()) + { + this.UpdateBuilder.DbColumnInfoList.ForEach(it => + { + var mappingInfo = identities.SingleOrDefault(i => it.DbColumnName.Equals(i, StringComparison.CurrentCultureIgnoreCase)); + if (mappingInfo != null && mappingInfo.Any()) + { + it.IsIdentity = true; + } + }); + } + #endregion + List primaryKey = GetPrimaryKeys(); + if (primaryKey != null && primaryKey.Count > 0) + { + this.UpdateBuilder.DbColumnInfoList.ForEach(it => + { + var mappingInfo = primaryKey.SingleOrDefault(i => it.DbColumnName.Equals(i, StringComparison.CurrentCultureIgnoreCase)); + if (mappingInfo != null && mappingInfo.Any()) + { + it.IsPrimarykey = true; + } + }); + } + if (this.UpdateBuilder.Parameters.HasValue() && this.UpdateBuilder.SetValues.IsValuable()) + { + this.UpdateBuilder.Parameters.RemoveAll(it => this.UpdateBuilder.SetValues.Any(v => (SqlBuilder.SqlParameterKeyWord + SqlBuilder.GetNoTranslationColumnName(v.Key)) == it.ParameterName)); + } + } + private string GetDbColumnName(string propertyName) + { + if (!IsMappingColumns) + { + return propertyName; + } + if (this.Context.MappingColumns.Any(it => it.EntityName.Equals(EntityInfo.EntityName, StringComparison.CurrentCultureIgnoreCase))) + { + this.MappingColumnList = this.Context.MappingColumns.Where(it => it.EntityName.Equals(EntityInfo.EntityName, StringComparison.CurrentCultureIgnoreCase)).ToList(); + } + if (MappingColumnList == null || !MappingColumnList.Any()) + { + return propertyName; + } + else + { + var mappInfo = this.MappingColumnList.FirstOrDefault(it => it.PropertyName.Equals(propertyName, StringComparison.CurrentCultureIgnoreCase)); + return mappInfo == null ? propertyName : mappInfo.DbColumnName; + } + } + private List GetPrimaryKeys() + { + if (this.WhereColumnList.HasValue()) + { + return this.WhereColumnList; + } + if (this.Context.IsSystemTablesConfig) + { + return this.Context.DbMaintenance.GetPrimaries(this.Context.EntityMaintenance.GetTableName(this.EntityInfo.EntityName)); + } + else + { + return this.EntityInfo.Columns.Where(it => it.IsPrimarykey).Select(it => it.DbColumnName).ToList(); + } + } + protected virtual List GetIdentityKeys() + { + if (this.Context.IsSystemTablesConfig) + { + return this.Context.DbMaintenance.GetIsIdentities(this.Context.EntityMaintenance.GetTableName(this.EntityInfo.EntityName)); + } + else + { + return this.EntityInfo.Columns.Where(it => it.IsIdentity).Select(it => it.DbColumnName).ToList(); + } + } + private void RestoreMapping() + { + if (IsAs) + { + this.Context.MappingTables = OldMappingTableList; + } + } + + + private void ValidateVersion() + { + var versionColumn = this.EntityInfo.Columns.FirstOrDefault(it => it.IsEnableUpdateVersionValidation); + var pks = this.UpdateBuilder.DbColumnInfoList.Where(it => it.IsPrimarykey).ToList(); + if (versionColumn != null && this.IsVersionValidation) + { + Check.Exception(pks.IsNullOrEmpty(), "UpdateVersionValidation the primary key is required."); + List conModels = new List(); + foreach (var item in pks) + { + conModels.Add(new ConditionalModel() { FieldName = item.DbColumnName, ConditionalType = ConditionalType.Equal, FieldValue = item.Value.ObjToString() }); + } + var dbInfo = this.Context.Queryable().Where(conModels).First(); + if (dbInfo != null) + { + var currentVersion = this.EntityInfo.Type.GetProperty(versionColumn.PropertyName).GetValue(UpdateObjs.Last(), null); + var dbVersion = this.EntityInfo.Type.GetProperty(versionColumn.PropertyName).GetValue(dbInfo, null); + Check.Exception(currentVersion == null, "UpdateVersionValidation entity property {0} is not null", versionColumn.PropertyName); + Check.Exception(dbVersion == null, "UpdateVersionValidation database column {0} is not null", versionColumn.DbColumnName); + if (versionColumn.PropertyInfo.PropertyType.IsIn(UtilConstants.IntType, UtilConstants.LongType)) + { + if (Convert.ToInt64(dbVersion) != Convert.ToInt64(currentVersion)) + { + throw new VersionExceptions(string.Format("UpdateVersionValidation {0} Not the latest version ", versionColumn.PropertyName)); + } + } + else if (versionColumn.PropertyInfo.PropertyType.IsIn(UtilConstants.DateType)) + { + if (dbVersion.ObjToDate() != currentVersion.ObjToDate()) + { + throw new VersionExceptions(string.Format("UpdateVersionValidation {0} Not the latest version ", versionColumn.PropertyName)); + } + } + else if (versionColumn.PropertyInfo.PropertyType.IsIn(UtilConstants.ByteArrayType)) + { + if (UtilMethods.GetLong((byte[])dbVersion) != UtilMethods.GetLong((byte[])currentVersion)) + { + throw new VersionExceptions(string.Format("UpdateVersionValidation {0} Not the latest version ", versionColumn.PropertyName)); + } + } + else + { + Check.ThrowNotSupportedException(string.Format("UpdateVersionValidation Not Supported Type [ {0} ] , {1}", versionColumn.PropertyInfo.PropertyType, versionColumn.PropertyName)); + } + } + } + } + private void After(string sql) + { + if (this.IsEnableDiffLogEvent) + { + var isDisableMasterSlaveSeparation = this.Ado.IsDisableMasterSlaveSeparation; + this.Ado.IsDisableMasterSlaveSeparation = true; + var parameters = UpdateBuilder.Parameters; + if (parameters == null) + parameters = new List(); + diffModel.AfterData = GetDiffTable(sql, parameters); + diffModel.Time = this.Context.Ado.SqlExecutionTime; + if (this.Context.CurrentConnectionConfig.AopEvents.OnDiffLogEvent != null) + this.Context.CurrentConnectionConfig.AopEvents.OnDiffLogEvent(diffModel); + this.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation; + } + if (this.RemoveCacheFunc != null) + { + this.RemoveCacheFunc(); + } + } + private string _ExecuteCommandWithOptLock(T updateData) + { + Check.ExceptionEasy(UpdateParameterIsNull == true, "Optimistic lock can only be an entity update method", "乐观锁只能是实体更新方式"); + var verColumn = this.EntityInfo.Columns.FirstOrDefault(it => it.IsEnableUpdateVersionValidation); + Check.ExceptionEasy(verColumn == null, $" {this.EntityInfo.EntityName } need IsEnableUpdateVersionValidation=true ", $"实体{this.EntityInfo.EntityName}没有找到版本标识特性 IsEnableUpdateVersionValidation"); + Check.ExceptionEasy(UpdateObjs.Length > 1, $"Optimistic lock can only handle a single update ", $"乐观锁只能处理单条更新"); + Check.ExceptionEasy(!verColumn.UnderType.IsIn(UtilConstants.StringType, UtilConstants.LongType, UtilConstants.GuidType, UtilConstants.DateType), $"Optimistic locks can only be guid, long, and string types", $"乐观锁只能是Guid、Long和字符串类型"); + var oldValue = verColumn.PropertyInfo.GetValue(updateData); + var newValue = UtilMethods.GetRandomByType(verColumn.UnderType); + verColumn.PropertyInfo.SetValue(updateData, newValue); + var data = this.UpdateBuilder.DbColumnInfoList.First(it => + it.PropertyName.EqualCase(verColumn.PropertyName)); + data.Value = newValue; + var pks = GetPrimaryKeys(); + Check.ExceptionEasy(pks.Count == 0, "need primary key or WhereColumn", "需要主键或者WhereColumn"); + this.Where(verColumn.DbColumnName, "=", oldValue); + foreach (var p in pks) + { + var pkColumn = this.EntityInfo.Columns.FirstOrDefault( + it => it.DbColumnName.EqualCase(p) || it.PropertyName.EqualCase(p)); + this.Where(pkColumn.DbColumnName, "=", pkColumn.PropertyInfo.GetValue(updateData)); + } + return verColumn.PropertyName; + } + private void Before(string sql) + { + if (this.IsEnableDiffLogEvent) + { + var isDisableMasterSlaveSeparation = this.Ado.IsDisableMasterSlaveSeparation; + this.Ado.IsDisableMasterSlaveSeparation = true; + var parameters = UpdateBuilder.Parameters; + if (parameters == null) + parameters = new List(); + diffModel.BeforeData = GetDiffTable(sql, parameters); + diffModel.Sql = sql; + diffModel.Parameters = parameters.ToArray(); + this.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation; + } + } + private bool IsPrimaryKey(DbColumnInfo it) + { + var result = GetPrimaryKeys().Any(p => p.Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase) || p.Equals(it.PropertyName, StringComparison.CurrentCultureIgnoreCase)); + return result; + } + + private List GetDiffTable(string sql, List parameters) + { + List result = new List(); + DataTable dt = null; + if (this.UpdateParameterIsNull) + { + var whereSql = Regex.Replace(sql, ".* WHERE ", "", RegexOptions.Singleline); + if (sql.Contains("WHERE (EXISTS")) + { + whereSql = Regex.Match(sql, @"\(EXISTS.+").Value; + } + dt = this.Context.Queryable().Filter(null, true).Where(whereSql).AddParameters(parameters).ToDataTable(); + } + else + { + if (this.UpdateObjs.ToList().Count == 0) + { + dt = new DataTable(); + } + else + { + dt = this.Context.Queryable().Filter(null, true).WhereClassByPrimaryKey(this.UpdateObjs.ToList()).ToDataTable(); + } + } + if (dt.Rows != null && dt.Rows.Count > 0) + { + foreach (DataRow row in dt.Rows) + { + DiffLogTableInfo item = new DiffLogTableInfo(); + item.TableDescription = this.EntityInfo.TableDescription; + item.TableName = this.EntityInfo.DbTableName; + item.Columns = new List(); + foreach (DataColumn col in dt.Columns) + { + var sugarColumn = this.EntityInfo.Columns.Where(it => it.DbColumnName != null).First(it => + it.DbColumnName.Equals(col.ColumnName, StringComparison.CurrentCultureIgnoreCase)); + DiffLogColumnInfo addItem = new DiffLogColumnInfo(); + addItem.Value = row[col.ColumnName]; + addItem.ColumnName = col.ColumnName; + addItem.IsPrimaryKey = sugarColumn.IsPrimarykey; + addItem.ColumnDescription = sugarColumn.ColumnDescription; + item.Columns.Add(addItem); + } + result.Add(item); + } + } + return result; + } + + private void ThrowUpdateByExpression() + { + Check.Exception(UpdateParameterIsNull == true, ErrorMessage.GetThrowMessage(" no support UpdateColumns and WhereColumns", "根据表达式更新 db.Updateable() 禁止使用 UpdateColumns和WhereColumns,你可以使用 SetColumns Where 等。更新分为2种方式 1.根据表达式更新 2.根据实体或者集合更新, 具体用法请查看文档 ")); + } + private void ThrowUpdateByObject() + { + Check.Exception(UpdateParameterIsNull == false, ErrorMessage.GetThrowMessage(" no support SetColumns and Where", "根据对像更新 db.Updateabe(对象) 禁止使用 SetColumns和Where ,你可以使用WhereColumns 和 UpdateColumns。 更新分为2种方式 1.根据表达式更新 2.根据实体或者集合更新 , 具体用法请查看文档 ")); + } + + } +} diff --git a/Src/Asp.NetCore2/SqlSugar/Abstract/UpdateProvider/UpdateableProvider.cs b/Src/Asp.NetCore2/SqlSugar/Abstract/UpdateProvider/UpdateableProvider.cs index a1d01657f..57e4cf617 100644 --- a/Src/Asp.NetCore2/SqlSugar/Abstract/UpdateProvider/UpdateableProvider.cs +++ b/Src/Asp.NetCore2/SqlSugar/Abstract/UpdateProvider/UpdateableProvider.cs @@ -9,7 +9,7 @@ using System.Threading.Tasks; namespace SqlSugar { - public class UpdateableProvider : IUpdateable where T : class, new() + public partial class UpdateableProvider : IUpdateable where T : class, new() { #region Property public SqlSugarProvider Context { get; internal set; } @@ -59,6 +59,20 @@ namespace SqlSugar var sqlObj = this.ToSql(); this.Context.Queues.Add(sqlObj.Key, sqlObj.Value); } + + public virtual int ExecuteCommandWithOptLock(bool IsVersionValidation=false) + { + var updateData = UpdateObjs.FirstOrDefault(); + if (updateData == null) return 0; + var name=_ExecuteCommandWithOptLock(updateData); + var result= this.ExecuteCommand(); + if (result == 0 && IsVersionValidation) + { + throw new VersionExceptions(string.Format("UpdateVersionValidation {0} Not the latest version ", name)); + } + return result; + } + public virtual int ExecuteCommand() { string sql = _ExecuteCommand(); @@ -70,10 +84,25 @@ namespace SqlSugar After(sql); return result; } + public bool ExecuteCommandHasChange() { return this.ExecuteCommand() > 0; } + + public virtual async Task ExecuteCommandWithOptLockAsync(bool IsVersionValidation = false) + { + var updateData = UpdateObjs.FirstOrDefault(); + if (updateData == null) return 0; + var name=_ExecuteCommandWithOptLock(updateData); + var result= await this.ExecuteCommandAsync(); + if (result == 0 && IsVersionValidation) + { + throw new VersionExceptions(string.Format("UpdateVersionValidation {0} Not the latest version ", name)); + } + return result; + } + public virtual async Task ExecuteCommandAsync() { string sql = _ExecuteCommand(); @@ -85,12 +114,14 @@ namespace SqlSugar After(sql); return result; } + public async Task ExecuteCommandHasChangeAsync() { return await this.ExecuteCommandAsync() > 0; } #endregion + #region Common public IUpdateable With(string lockString) { if (this.Context.CurrentConnectionConfig.DbType == DbType.SqlServer) @@ -108,7 +139,7 @@ namespace SqlSugar }; var tables = getTableNamesFunc(helper.GetTables()); result.Tables = tables; - result.updateobj= this; + result.updateobj = this; return result; } public SplitTableUpdateByObjectProvider SplitTable() @@ -138,7 +169,7 @@ namespace SqlSugar this.RemoveCacheFunc = () => { var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; - CacheSchemeMain.RemoveCacheByLike(cacheService,likeString); + CacheSchemeMain.RemoveCacheByLike(cacheService, likeString); }; return this; } @@ -207,7 +238,7 @@ namespace SqlSugar } - public IUpdateable ReSetValue(Action setValueExpression) + public IUpdateable ReSetValue(Action setValueExpression) { ThrowUpdateByExpression(); if (this.UpdateObjs.HasValue()) @@ -222,7 +253,8 @@ namespace SqlSugar this.UpdateBuilder.DbColumnInfoList = this.UpdateBuilder.DbColumnInfoList.Where(it => oldColumns.Contains(it.PropertyName)).ToList(); } return this; - } + } + #endregion #region Update by object public IUpdateable CallEntityMethod(Expression> method) @@ -464,473 +496,5 @@ namespace SqlSugar } #endregion - #region Helper - - private bool UpdateObjectNotWhere() - { - return this.Context.CurrentConnectionConfig.DbType != DbType.MySql - && this.Context.CurrentConnectionConfig.DbType!=DbType.MySqlConnector - && this.Context.CurrentConnectionConfig.DbType != DbType.SqlServer; - } - - private void AppendSets() - { - if (SetColumnsIndex > 0) - { - var keys = UpdateBuilder.SetValues.Select(it => SqlBuilder.GetNoTranslationColumnName(it.Key.ToLower())).ToList(); - var addKeys = keys.Where(k => !this.UpdateBuilder.DbColumnInfoList.Any(it => it.PropertyName.ToLower() == k || it.DbColumnName.ToLower() == k)).ToList(); - var addItems = this.EntityInfo.Columns.Where(it => !GetPrimaryKeys().Any(p => p.ToLower() == it.PropertyName?.ToLower() || p.ToLower() == it.DbColumnName?.ToLower()) && addKeys.Any(k => it.PropertyName?.ToLower() == k || it.DbColumnName?.ToLower() == k)).ToList(); - this.UpdateBuilder.DbColumnInfoList.AddRange(addItems.Select(it => new DbColumnInfo() { PropertyName = it.PropertyName, DbColumnName = it.DbColumnName })); - } - SetColumnsIndex++; - } - private string _ExecuteCommand() - { - PreToSql(); - AutoRemoveDataCache(); - Check.Exception(UpdateBuilder.WhereValues.IsNullOrEmpty() && GetPrimaryKeys().IsNullOrEmpty(), "You cannot have no primary key and no conditions"); - string sql = UpdateBuilder.ToSqlString(); - ValidateVersion(); - RestoreMapping(); - Before(sql); - return sql; - } - - private void _WhereColumn(string columnName) - { - var columnInfos = columns.Where(it => it.DbColumnName.Equals(columnName, StringComparison.OrdinalIgnoreCase) || it.PropertyName.Equals(columnName, StringComparison.OrdinalIgnoreCase)).ToList(); - if (!this.UpdateBuilder.DbColumnInfoList.Any(y => y.DbColumnName == columnInfos.First().DbColumnName)) - { - this.UpdateBuilder.DbColumnInfoList.AddRange(columnInfos); - } - } - - private void AutoRemoveDataCache() - { - var moreSetts = this.Context.CurrentConnectionConfig.MoreSettings; - var extService = this.Context.CurrentConnectionConfig.ConfigureExternalServices; - if (moreSetts != null && moreSetts.IsAutoRemoveDataCache && extService != null && extService.DataInfoCacheService != null) - { - this.RemoveDataCache(); - } - } - internal void Init() - { - this.UpdateBuilder.TableName = EntityInfo.EntityName; - if (IsMappingTable) - { - var mappingInfo = this.Context.MappingTables.SingleOrDefault(it => it.EntityName == EntityInfo.EntityName); - if (mappingInfo != null) - { - this.UpdateBuilder.TableName = mappingInfo.DbTableName; - } - } - //Check.Exception(UpdateObjs == null || UpdateObjs.Count() == 0, "UpdateObjs is null"); - int i = 0; - foreach (var item in UpdateObjs) - { - List updateItem = new List(); - var isDic = item is Dictionary; - if (isDic) - { - SetUpdateItemByDic(i, item, updateItem); - } - else - { - DataAop(item); - SetUpdateItemByEntity(i, item, updateItem); - } - ++i; - } - this.columns = this.UpdateBuilder.DbColumnInfoList; - - var ignoreColumns = EntityInfo.Columns.Where(it => it.IsOnlyIgnoreUpdate).ToList(); - if (ignoreColumns != null && ignoreColumns.Any()) - { - this.IgnoreColumns(ignoreColumns.Select(it => it.PropertyName).ToArray()); - } - } - - private void DataAop(T item) - { - var dataEvent = this.Context.CurrentConnectionConfig.AopEvents?.DataExecuting; - if (dataEvent != null && item != null) - { - foreach (var columnInfo in this.EntityInfo.Columns) - { - dataEvent(columnInfo.PropertyInfo.GetValue(item, null), new DataFilterModel() { OperationType = DataFilterType.UpdateByObject, EntityValue = item, EntityColumnInfo = columnInfo }); - } - } - } - - private void CheckTranscodeing(bool checkIsJson = true) - { - if (this.EntityInfo.Columns.Any(it => it.IsTranscoding)) - { - Check.Exception(true, ErrorMessage.GetThrowMessage("UpdateColumns no support IsTranscoding", "SetColumns方式更新不支持IsTranscoding,你可以使用db.Updateable(实体)的方式更新")); - } - if (checkIsJson && this.EntityInfo.Columns.Any(it => it.IsJson)) - { - Check.Exception(true, ErrorMessage.GetThrowMessage("UpdateColumns no support IsJson", "SetColumns方式更新不支持IsJson,你可以使用db.Updateable(实体)的方式更新")); - } - if (this.EntityInfo.Columns.Any(it => it.IsArray)) - { - Check.Exception(true, ErrorMessage.GetThrowMessage("UpdateColumns no support IsArray", "SetColumns方式更新不支持IsArray,你可以使用db.Updateable(实体)的方式更新")); - } - } - private void SetUpdateItemByDic(int i, T item, List updateItem) - { - foreach (var column in item as Dictionary) - { - var columnInfo = new DbColumnInfo() - { - Value = column.Value, - DbColumnName = column.Key, - PropertyName = column.Key, - PropertyType = column.Value == null ? DBNull.Value.GetType() : UtilMethods.GetUnderType(column.Value.GetType()), - TableId = i - }; - if (columnInfo.PropertyType.IsEnum()) - { - if (this.Context.CurrentConnectionConfig.MoreSettings?.TableEnumIsString == true) - { - columnInfo.PropertyType = UtilConstants.StringType; - columnInfo.Value = columnInfo.Value.ToString(); - } - else - { - columnInfo.Value = Convert.ToInt64(columnInfo.Value); - } - } - updateItem.Add(columnInfo); - } - this.UpdateBuilder.DbColumnInfoList.AddRange(updateItem); - } - private void SetUpdateItemByEntity(int i, T item, List updateItem) - { - foreach (var column in EntityInfo.Columns) - { - if (column.IsIgnore) continue; - var columnInfo = new DbColumnInfo() - { - Value = column.PropertyInfo.GetValue(item, null), - DbColumnName = GetDbColumnName(column.PropertyName), - PropertyName = column.PropertyName, - PropertyType = UtilMethods.GetUnderType(column.PropertyInfo), - TableId = i - }; - if (columnInfo.PropertyType.IsEnum()&& columnInfo.Value!=null) - { - if (this.Context.CurrentConnectionConfig.MoreSettings?.TableEnumIsString == true) - { - columnInfo.PropertyType = UtilConstants.StringType; - columnInfo.Value = columnInfo.Value.ToString(); - } - else - { - columnInfo.Value = Convert.ToInt64(columnInfo.Value); - } - } - if (column.IsJson) - { - columnInfo.IsJson = true; - if (columnInfo.Value != null) - columnInfo.Value = this.Context.Utilities.SerializeObject(columnInfo.Value); - } - if (column.IsArray) - { - columnInfo.IsArray = true; - } - var tranColumn = EntityInfo.Columns.FirstOrDefault(it => it.IsTranscoding && it.DbColumnName.Equals(column.DbColumnName, StringComparison.CurrentCultureIgnoreCase)); - if (tranColumn != null && columnInfo.Value.HasValue()) - { - columnInfo.Value = UtilMethods.EncodeBase64(columnInfo.Value.ToString()); - } - updateItem.Add(columnInfo); - } - this.UpdateBuilder.DbColumnInfoList.AddRange(updateItem); - } - - private void PreToSql() - { - - UpdateBuilder.PrimaryKeys = GetPrimaryKeys(); - if (this.IsWhereColumns) - { - foreach (var pkName in UpdateBuilder.PrimaryKeys) - { - if (WhereColumnList != null&& WhereColumnList.Count()>0) - { - continue; - } - var isContains = this.UpdateBuilder.DbColumnInfoList.Select(it => it.DbColumnName.ToLower()).Contains(pkName.ToLower()); - Check.Exception(isContains == false, "Use UpdateColumns().WhereColumn() ,UpdateColumns need {0}", pkName); - } - } - #region IgnoreColumns - if (this.Context.IgnoreColumns != null && this.Context.IgnoreColumns.Any()) - { - var currentIgnoreColumns = this.Context.IgnoreColumns.Where(it => it.EntityName == this.EntityInfo.EntityName).ToList(); - this.UpdateBuilder.DbColumnInfoList = this.UpdateBuilder.DbColumnInfoList.Where(it => - { - return !currentIgnoreColumns.Any(i => it.PropertyName.Equals(i.PropertyName, StringComparison.CurrentCulture)); - }).ToList(); - } - #endregion - if (this.IsSingle) - { - foreach (var item in this.UpdateBuilder.DbColumnInfoList) - { - if (this.UpdateBuilder.Parameters == null) this.UpdateBuilder.Parameters = new List(); - if (this.UpdateBuilder.SetValues.Any(it => this.SqlBuilder.GetNoTranslationColumnName(it.Key) == item.PropertyName)) - { - continue; - } - var parameter = new SugarParameter(this.SqlBuilder.SqlParameterKeyWord + item.DbColumnName, item.Value, item.PropertyType); - if (item.IsJson) - { - parameter.IsJson = true; - } - if (item.IsArray) - { - parameter.IsArray = true; - } - this.UpdateBuilder.Parameters.Add(parameter); - } - } - - #region Identities - List identities = GetIdentityKeys(); - if (identities != null && identities.Any()) - { - this.UpdateBuilder.DbColumnInfoList.ForEach(it => - { - var mappingInfo = identities.SingleOrDefault(i => it.DbColumnName.Equals(i, StringComparison.CurrentCultureIgnoreCase)); - if (mappingInfo != null && mappingInfo.Any()) - { - it.IsIdentity = true; - } - }); - } - #endregion - List primaryKey = GetPrimaryKeys(); - if (primaryKey != null && primaryKey.Count > 0) - { - this.UpdateBuilder.DbColumnInfoList.ForEach(it => - { - var mappingInfo = primaryKey.SingleOrDefault(i => it.DbColumnName.Equals(i, StringComparison.CurrentCultureIgnoreCase)); - if (mappingInfo != null && mappingInfo.Any()) - { - it.IsPrimarykey = true; - } - }); - } - if (this.UpdateBuilder.Parameters.HasValue() && this.UpdateBuilder.SetValues.IsValuable()) - { - this.UpdateBuilder.Parameters.RemoveAll(it => this.UpdateBuilder.SetValues.Any(v => (SqlBuilder.SqlParameterKeyWord + SqlBuilder.GetNoTranslationColumnName(v.Key)) == it.ParameterName)); - } - } - private string GetDbColumnName(string propertyName) - { - if (!IsMappingColumns) - { - return propertyName; - } - if (this.Context.MappingColumns.Any(it => it.EntityName.Equals(EntityInfo.EntityName, StringComparison.CurrentCultureIgnoreCase))) - { - this.MappingColumnList = this.Context.MappingColumns.Where(it => it.EntityName.Equals(EntityInfo.EntityName, StringComparison.CurrentCultureIgnoreCase)).ToList(); - } - if (MappingColumnList == null || !MappingColumnList.Any()) - { - return propertyName; - } - else - { - var mappInfo = this.MappingColumnList.FirstOrDefault(it => it.PropertyName.Equals(propertyName, StringComparison.CurrentCultureIgnoreCase)); - return mappInfo == null ? propertyName : mappInfo.DbColumnName; - } - } - private List GetPrimaryKeys() - { - if (this.WhereColumnList.HasValue()) - { - return this.WhereColumnList; - } - if (this.Context.IsSystemTablesConfig) - { - return this.Context.DbMaintenance.GetPrimaries(this.Context.EntityMaintenance.GetTableName(this.EntityInfo.EntityName)); - } - else - { - return this.EntityInfo.Columns.Where(it => it.IsPrimarykey).Select(it => it.DbColumnName).ToList(); - } - } - protected virtual List GetIdentityKeys() - { - if (this.Context.IsSystemTablesConfig) - { - return this.Context.DbMaintenance.GetIsIdentities(this.Context.EntityMaintenance.GetTableName(this.EntityInfo.EntityName)); - } - else - { - return this.EntityInfo.Columns.Where(it => it.IsIdentity).Select(it => it.DbColumnName).ToList(); - } - } - private void RestoreMapping() - { - if (IsAs) - { - this.Context.MappingTables = OldMappingTableList; - } - } - - - private void ValidateVersion() - { - var versionColumn = this.EntityInfo.Columns.FirstOrDefault(it => it.IsEnableUpdateVersionValidation); - var pks = this.UpdateBuilder.DbColumnInfoList.Where(it => it.IsPrimarykey).ToList(); - if (versionColumn != null && this.IsVersionValidation) - { - Check.Exception(pks.IsNullOrEmpty(), "UpdateVersionValidation the primary key is required."); - List conModels = new List(); - foreach (var item in pks) - { - conModels.Add(new ConditionalModel() { FieldName = item.DbColumnName, ConditionalType = ConditionalType.Equal, FieldValue = item.Value.ObjToString() }); - } - var dbInfo = this.Context.Queryable().Where(conModels).First(); - if (dbInfo != null) - { - var currentVersion = this.EntityInfo.Type.GetProperty(versionColumn.PropertyName).GetValue(UpdateObjs.Last(), null); - var dbVersion = this.EntityInfo.Type.GetProperty(versionColumn.PropertyName).GetValue(dbInfo, null); - Check.Exception(currentVersion == null, "UpdateVersionValidation entity property {0} is not null", versionColumn.PropertyName); - Check.Exception(dbVersion == null, "UpdateVersionValidation database column {0} is not null", versionColumn.DbColumnName); - if (versionColumn.PropertyInfo.PropertyType.IsIn(UtilConstants.IntType, UtilConstants.LongType)) - { - if (Convert.ToInt64(dbVersion) != Convert.ToInt64(currentVersion)) - { - throw new VersionExceptions(string.Format("UpdateVersionValidation {0} Not the latest version ", versionColumn.PropertyName)); - } - } - else if (versionColumn.PropertyInfo.PropertyType.IsIn(UtilConstants.DateType)) - { - if (dbVersion.ObjToDate() != currentVersion.ObjToDate()) - { - throw new VersionExceptions(string.Format("UpdateVersionValidation {0} Not the latest version ", versionColumn.PropertyName)); - } - } - else if (versionColumn.PropertyInfo.PropertyType.IsIn(UtilConstants.ByteArrayType)) - { - if (UtilMethods.GetLong((byte[])dbVersion) != UtilMethods.GetLong((byte[])currentVersion)) - { - throw new VersionExceptions(string.Format("UpdateVersionValidation {0} Not the latest version ", versionColumn.PropertyName)); - } - } - else - { - Check.ThrowNotSupportedException(string.Format("UpdateVersionValidation Not Supported Type [ {0} ] , {1}", versionColumn.PropertyInfo.PropertyType, versionColumn.PropertyName)); - } - } - } - } - private void After(string sql) - { - if (this.IsEnableDiffLogEvent) - { - var isDisableMasterSlaveSeparation = this.Ado.IsDisableMasterSlaveSeparation; - this.Ado.IsDisableMasterSlaveSeparation = true; - var parameters = UpdateBuilder.Parameters; - if (parameters == null) - parameters = new List(); - diffModel.AfterData = GetDiffTable(sql, parameters); - diffModel.Time = this.Context.Ado.SqlExecutionTime; - if (this.Context.CurrentConnectionConfig.AopEvents.OnDiffLogEvent != null) - this.Context.CurrentConnectionConfig.AopEvents.OnDiffLogEvent(diffModel); - this.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation; - } - if (this.RemoveCacheFunc != null) - { - this.RemoveCacheFunc(); - } - } - - private void Before(string sql) - { - if (this.IsEnableDiffLogEvent) - { - var isDisableMasterSlaveSeparation = this.Ado.IsDisableMasterSlaveSeparation; - this.Ado.IsDisableMasterSlaveSeparation = true; - var parameters = UpdateBuilder.Parameters; - if (parameters == null) - parameters = new List(); - diffModel.BeforeData = GetDiffTable(sql, parameters); - diffModel.Sql = sql; - diffModel.Parameters = parameters.ToArray(); - this.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation; - } - } - private bool IsPrimaryKey(DbColumnInfo it) - { - var result = GetPrimaryKeys().Any(p => p.Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase) || p.Equals(it.PropertyName, StringComparison.CurrentCultureIgnoreCase)); - return result; - } - - private List GetDiffTable(string sql, List parameters) - { - List result = new List(); - DataTable dt = null; - if (this.UpdateParameterIsNull) - { - var whereSql = Regex.Replace(sql, ".* WHERE ", "", RegexOptions.Singleline); - if (sql.Contains("WHERE (EXISTS")) - { - whereSql=Regex.Match(sql, @"\(EXISTS.+").Value; - } - dt = this.Context.Queryable().Filter(null, true).Where(whereSql).AddParameters(parameters).ToDataTable(); - } - else - { - if (this.UpdateObjs.ToList().Count == 0) - { - dt = new DataTable(); - } - else - { - dt = this.Context.Queryable().Filter(null, true).WhereClassByPrimaryKey(this.UpdateObjs.ToList()).ToDataTable(); - } - } - if (dt.Rows != null && dt.Rows.Count > 0) - { - foreach (DataRow row in dt.Rows) - { - DiffLogTableInfo item = new DiffLogTableInfo(); - item.TableDescription = this.EntityInfo.TableDescription; - item.TableName = this.EntityInfo.DbTableName; - item.Columns = new List(); - foreach (DataColumn col in dt.Columns) - { - var sugarColumn = this.EntityInfo.Columns.Where(it => it.DbColumnName != null).First(it => - it.DbColumnName.Equals(col.ColumnName, StringComparison.CurrentCultureIgnoreCase)); - DiffLogColumnInfo addItem = new DiffLogColumnInfo(); - addItem.Value = row[col.ColumnName]; - addItem.ColumnName = col.ColumnName; - addItem.IsPrimaryKey = sugarColumn.IsPrimarykey; - addItem.ColumnDescription = sugarColumn.ColumnDescription; - item.Columns.Add(addItem); - } - result.Add(item); - } - } - return result; - } - - private void ThrowUpdateByExpression() - { - Check.Exception(UpdateParameterIsNull == true, ErrorMessage.GetThrowMessage(" no support UpdateColumns and WhereColumns", "根据表达式更新 db.Updateable() 禁止使用 UpdateColumns和WhereColumns,你可以使用 SetColumns Where 等。更新分为2种方式 1.根据表达式更新 2.根据实体或者集合更新, 具体用法请查看文档 ")); - } - private void ThrowUpdateByObject() - { - Check.Exception(UpdateParameterIsNull == false, ErrorMessage.GetThrowMessage(" no support SetColumns and Where", "根据对像更新 db.Updateabe(对象) 禁止使用 SetColumns和Where ,你可以使用WhereColumns 和 UpdateColumns。 更新分为2种方式 1.根据表达式更新 2.根据实体或者集合更新 , 具体用法请查看文档 ")); - } - #endregion } } diff --git a/Src/Asp.NetCore2/SqlSugar/Interface/IUpdateable.cs b/Src/Asp.NetCore2/SqlSugar/Interface/IUpdateable.cs index 56e5703b4..7f717dfeb 100644 --- a/Src/Asp.NetCore2/SqlSugar/Interface/IUpdateable.cs +++ b/Src/Asp.NetCore2/SqlSugar/Interface/IUpdateable.cs @@ -12,6 +12,8 @@ namespace SqlSugar UpdateBuilder UpdateBuilder { get; set; } bool UpdateParameterIsNull { get; set; } + int ExecuteCommandWithOptLock(bool isThrowError = false); + Task ExecuteCommandWithOptLockAsync(bool isThrowError = false); int ExecuteCommand(); bool ExecuteCommandHasChange(); Task ExecuteCommandAsync(); diff --git a/Src/Asp.NetCore2/SqlSugar/Utilities/UtilMethods.cs b/Src/Asp.NetCore2/SqlSugar/Utilities/UtilMethods.cs index 8ff8b35f1..2ac280d1c 100644 --- a/Src/Asp.NetCore2/SqlSugar/Utilities/UtilMethods.cs +++ b/Src/Asp.NetCore2/SqlSugar/Utilities/UtilMethods.cs @@ -133,6 +133,30 @@ namespace SqlSugar }; } + internal static object GetRandomByType(Type underType) + { + if (underType == UtilConstants.GuidType) + { + return Guid.NewGuid(); + } + else if (underType == UtilConstants.LongType) + { + return SnowFlakeSingle.Instance.NextId(); + } + else if (underType == UtilConstants.StringType) + { + return Guid.NewGuid() + ""; + } + else if (underType == UtilConstants.DateType) + { + return System.DateTime.Now; + } + else + { + return Guid.NewGuid() + ""; + } + } + public static bool IsAsyncMethod(MethodBase method) { if (method == null)