using System; using System.Collections.Generic; using System.Data; using System.Text; using System.Threading.Tasks; using System.Linq; namespace SqlSugar { public partial class FastestProvider:IFastest where T:class,new() { internal SqlSugarProvider context; private ISugarQueryable queryable; private EntityInfo entityInfo { get; set; } public bool isLog; public FastestProvider(SqlSugarProvider sqlSugarProvider) { this.context = sqlSugarProvider; this.queryable = this.context.Queryable(); entityInfo=this.context.EntityMaintenance.GetEntityInfo(); } #region BulkCopy public int BulkCopy(string tableName,DataTable dt) { return BulkCopyAsync(tableName,dt).ConfigureAwait(true).GetAwaiter().GetResult(); } public int BulkCopy(DataTable dt) { Check.ExceptionEasy(this.AsName.IsNullOrEmpty(), "need .AS(tablaeName) ", "需要 .AS(tablaeName) 设置表名"); return BulkCopyAsync(this.AsName, dt).ConfigureAwait(true).GetAwaiter().GetResult(); } public Task BulkCopyAsync(DataTable dt) { Check.ExceptionEasy(this.AsName.IsNullOrEmpty(), "need .AS(tablaeName) ", "需要 .AS(tablaeName) 设置表名"); return BulkCopyAsync(this.AsName, dt); } public async Task BulkCopyAsync(string tableName, DataTable dt) { if (Size > 0) { int resul = 0; await this.context.Utilities.PageEachAsync(dt.Rows.Cast().ToList(), Size, async item => { resul += await _BulkCopy(tableName,item.CopyToDataTable()); }); return resul; } else { return await _BulkCopy(tableName,dt); } } public int BulkCopy(List datas) { return BulkCopyAsync(datas).ConfigureAwait(true).GetAwaiter().GetResult(); } public async Task BulkCopyAsync(List datas) { if (Size > 0) { int resul=0; await this.context.Utilities.PageEachAsync(datas, Size, async item => { resul+= await _BulkCopy(item); }); return resul; } else { return await _BulkCopy(datas); } } #endregion #region BulkUpdate public int BulkUpdate(List datas) { return BulkUpdateAsync(datas).ConfigureAwait(true).GetAwaiter().GetResult(); } public async Task BulkUpdateAsync(List datas) { var whereColumns=entityInfo.Columns.Where(it => it.IsPrimarykey).Select(it=>it.DbColumnName??it.PropertyName).ToArray(); var updateColumns = entityInfo.Columns.Where(it => !it.IsPrimarykey&&!it.IsIdentity&&!it.IsOnlyIgnoreUpdate&&!it.IsIgnore).Select(it => it.DbColumnName ?? it.PropertyName).ToArray(); return await BulkUpdateAsync(datas,whereColumns,updateColumns); } public int BulkUpdate(List datas, string[] whereColumns, string[] updateColumns) { whereColumns = whereColumns.Select(x => this.entityInfo.Columns.FirstOrDefault(it => it.PropertyName.EqualCase(x) || it.DbColumnName.EqualCase(x))?.DbColumnName ?? x).ToArray(); updateColumns = updateColumns.Select(x => this.entityInfo.Columns.FirstOrDefault(it => it.PropertyName.EqualCase(x) || it.DbColumnName.EqualCase(x))?.DbColumnName ?? x).ToArray(); return BulkUpdateAsync(datas,whereColumns,updateColumns).ConfigureAwait(true).GetAwaiter().GetResult(); } public int BulkUpdate(List datas, string[] whereColumns) { return BulkUpdateAsync(datas, whereColumns).GetAwaiter().GetResult(); } public async Task BulkUpdateAsync(List datas, string[] whereColumns) { whereColumns = whereColumns.Select(x => this.entityInfo.Columns.FirstOrDefault(it => it.PropertyName.EqualCase(x) || it.DbColumnName.EqualCase(x))?.DbColumnName ?? x).ToArray(); var updateColumns = this.entityInfo.Columns .Where(it => !whereColumns.Any(z => z.EqualCase(it.DbColumnName))) .Where(it => !it.IsIdentity) .Where(it => !it.IsPrimarykey) .Where(it => !it.IsOnlyIgnoreUpdate) .Where(it => !it.IsIgnore) .Select(it => it.DbColumnName) .ToArray(); return await BulkUpdateAsync(datas, whereColumns, updateColumns).ConfigureAwait(true); } public async Task BulkUpdateAsync(List datas,string [] whereColumns,string [] updateColumns) { if (Size > 0) { int resul = 0; await this.context.Utilities.PageEachAsync(datas, Size, async item => { resul += await _BulkUpdate(item, whereColumns, updateColumns); }); return resul; } else { return await _BulkUpdate(datas, whereColumns, updateColumns); } } public int BulkUpdate(string tableName,DataTable dataTable, string[] whereColumns, string[] updateColumns) { return BulkUpdateAsync(tableName,dataTable, whereColumns, updateColumns).ConfigureAwait(true).GetAwaiter().GetResult(); } public int BulkUpdate(DataTable dataTable, string[] whereColumns, string[] updateColumns) { Check.ExceptionEasy(this.AsName.IsNullOrEmpty(), "need .AS(tablaeName) ", "需要 .AS(tablaeName) 设置表名"); return BulkUpdateAsync(this.AsName, dataTable, whereColumns, updateColumns).ConfigureAwait(true).GetAwaiter().GetResult(); } public int BulkUpdate(DataTable dataTable, string[] whereColumns) { string[] updateColumns = dataTable.Columns.Cast().Select(it => it.ColumnName).Where(it => !whereColumns.Any(z => z.EqualCase(it))).ToArray(); Check.ExceptionEasy(this.AsName.IsNullOrEmpty(), "need .AS(tablaeName) ", "需要 .AS(tablaeName) 设置表名"); return BulkUpdateAsync(this.AsName, dataTable, whereColumns, updateColumns).ConfigureAwait(true).GetAwaiter().GetResult(); } public Task BulkUpdateAsync(DataTable dataTable, string[] whereColumns) { string[] updateColumns = dataTable.Columns.Cast().Select(it => it.ColumnName).Where(it => !whereColumns.Any(z => z.EqualCase(it))).ToArray(); Check.ExceptionEasy(this.AsName.IsNullOrEmpty(), "need .AS(tablaeName) ", "需要 .AS(tablaeName) 设置表名"); return BulkUpdateAsync(this.AsName, dataTable, whereColumns, updateColumns); } public async Task BulkUpdateAsync(string tableName, DataTable dataTable, string[] whereColumns, string[] updateColumns) { if (Size > 0) { int resul = 0; await this.context.Utilities.PageEachAsync(dataTable.Rows.Cast().ToList(), Size, async item => { resul += await _BulkUpdate(tableName,item.CopyToDataTable(), whereColumns, updateColumns); }); return resul; } else { return await _BulkUpdate(tableName,dataTable, whereColumns, updateColumns); } } #endregion #region Core private async Task _BulkUpdate(List datas, string[] whereColumns, string[] updateColumns) { Begin(datas,false); Check.Exception(whereColumns == null || whereColumns.Count() == 0, "where columns count=0 or need primary key"); Check.Exception(updateColumns == null || updateColumns.Count() == 0, "set columns count=0"); var isAuto = this.context.CurrentConnectionConfig.IsAutoCloseConnection; this.context.CurrentConnectionConfig.IsAutoCloseConnection = false; DataTable dt = ToDdateTable(datas); IFastBuilder buider = GetBuider(); ActionIgnoreColums(whereColumns, updateColumns, dt, buider.IsActionUpdateColumns); buider.Context = context; await buider.CreateTempAsync(dt); await buider.ExecuteBulkCopyAsync(dt); //var queryTemp = this.context.Queryable().AS(dt.TableName).ToList();//test var result = await buider.UpdateByTempAsync(GetTableName(), dt.TableName, updateColumns, whereColumns); if (this.context.CurrentConnectionConfig.DbType != DbType.Sqlite) { this.context.DbMaintenance.DropTable(dt.TableName); } this.context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto; buider.CloseDb(); End(datas, false); return result; } private void ActionIgnoreColums(string[] whereColumns, string[] updateColumns, DataTable dt,bool IsActionUpdateColumns) { if (entityInfo.Columns.Where(it => it.IsIgnore == false).Count() > whereColumns.Length + updateColumns.Length &&IsActionUpdateColumns) { var ignoreColums = dt.Columns.Cast() .Where(it => !whereColumns.Any(y => y.EqualCase(it.ColumnName))) .Where(it => !updateColumns.Any(y => y.EqualCase(it.ColumnName))).ToList(); foreach (DataRow item in dt.Rows) { foreach (var col in ignoreColums) { if (item[col.ColumnName].IsNullOrEmpty()) { if (col.DataType == UtilConstants.StringType) { item[col.ColumnName] = string.Empty; } else if (col.DataType == UtilConstants.DateType) { item[col.ColumnName] =UtilMethods.GetMinDate(this.context.CurrentConnectionConfig); } else { item[col.ColumnName] = Activator.CreateInstance(col.DataType); } } } } } } private async Task _BulkUpdate(string tableName,DataTable dataTable, string[] whereColumns, string[] updateColumns) { var datas = new string[dataTable.Rows.Count].ToList(); Begin(datas, false); Check.Exception(whereColumns == null || whereColumns.Count() == 0, "where columns count=0 or need primary key"); Check.Exception(updateColumns == null || updateColumns.Count() == 0, "set columns count=0"); var isAuto = this.context.CurrentConnectionConfig.IsAutoCloseConnection; this.context.CurrentConnectionConfig.IsAutoCloseConnection = false; dataTable.TableName = this.queryable.SqlBuilder.GetTranslationTableName(tableName); DataTable dt = GetCopyWriteDataTable(dataTable); IFastBuilder buider = GetBuider(); if (dt.Columns.Count != dataTable.Columns.Count) { ActionIgnoreColums(whereColumns, updateColumns, dt, buider.IsActionUpdateColumns); } buider.Context = context; await buider.CreateTempAsync(dt); await buider.ExecuteBulkCopyAsync(dt); //var queryTemp = this.context.Queryable().AS(dt.TableName).ToList();//test var result = await buider.UpdateByTempAsync(GetTableName(), dt.TableName, updateColumns, whereColumns); this.context.DbMaintenance.DropTable(dt.TableName); this.context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto; buider.CloseDb(); End(datas, false); return result; } private async Task _BulkCopy(List datas) { Begin(datas,true); DataTable dt = ToDdateTable(datas); IFastBuilder buider =GetBuider(); buider.Context = context; var result = await buider.ExecuteBulkCopyAsync(dt); End(datas,true); return result; } private async Task _BulkCopy(string tableName,DataTable dataTable) { var datas =new string[dataTable.Rows.Count].ToList(); Begin(datas, true); DataTable dt = dataTable; dt.TableName =this.queryable.SqlBuilder.GetTranslationTableName(tableName); dt = GetCopyWriteDataTable(dt); IFastBuilder buider = GetBuider(); buider.Context = context; var result = await buider.ExecuteBulkCopyAsync(dt); End(datas, true); return result; } #endregion #region AOP private void End(List datas,bool isAdd) { var title = isAdd ? "BulkCopy" : "BulkUpdate"; this.context.Ado.IsEnableLogEvent = isLog; if (this.context.CurrentConnectionConfig?.AopEvents?.OnLogExecuted != null) { this.context.CurrentConnectionConfig?.AopEvents?.OnLogExecuted($"End {title} name:{GetTableName()} ,count: {datas.Count},current time: {DateTime.Now}", new SugarParameter[] { }); } RemoveCache(); } private void Begin(List datas,bool isAdd) { var title = isAdd ? "BulkCopy" : "BulkUpdate"; isLog = this.context.Ado.IsEnableLogEvent; this.context.Ado.IsEnableLogEvent = false; if (this.context.CurrentConnectionConfig?.AopEvents?.OnLogExecuting != null) { this.context.CurrentConnectionConfig?.AopEvents?.OnLogExecuting($"Begin {title} name:{GetTableName()} ,count: {datas.Count},current time: {DateTime.Now} ", new SugarParameter[] { }); } } #endregion } }