using System.Data;
using System.Reflection;
namespace ThingsGateway.SqlSugar
{
    public partial class FastestProvider<T> : IFastest<T> where T : class, new()
    {
        /// <summary>SqlSugar上下文实例</summary>
        internal SqlSugarProvider context;
        /// <summary>可查询对象</summary>
        private ISugarQueryable<T> queryable;
        /// <summary>实体信息</summary>
        private EntityInfo entityInfo { get; set; }
        /// <summary>是否记录日志</summary>
        public bool isLog;
        /// <summary>构造函数</summary>
        public FastestProvider(SqlSugarProvider sqlSugarProvider)
        {
            this.context = sqlSugarProvider;
            this.queryable = this.context.Queryable<T>();
            entityInfo = this.context.EntityMaintenance.GetEntityInfo<T>();
        }

        #region BulkCopy
        /// <summary>批量插入DataTable数据</summary>
        public int BulkCopy(string tableName, DataTable dt)
        {
            return BulkCopyAsync(tableName, dt).ConfigureAwait(true).GetAwaiter().GetResult();
        }
        /// <summary>批量插入DataTable数据</summary>
        public int BulkCopy(DataTable dt)
        {
            Check.ExceptionEasy(this.AsName.IsNullOrEmpty(), "need .AS(tablaeName) ", "需要 .AS(tablaeName) 设置表名");
            return BulkCopyAsync(this.AsName, dt).ConfigureAwait(true).GetAwaiter().GetResult();
        }
        /// <summary>异步批量插入DataTable数据</summary>
        public Task<int> BulkCopyAsync(DataTable dt)
        {
            Check.ExceptionEasy(this.AsName.IsNullOrEmpty(), "need .AS(tablaeName) ", "需要 .AS(tablaeName) 设置表名");
            return BulkCopyAsync(this.AsName, dt);
        }
        /// <summary>异步批量插入DataTable数据</summary>
        public async Task<int> BulkCopyAsync(string tableName, DataTable dt)
        {
            if (Size > 0)
            {
                int resul = 0;
                await context.Utilities.PageEachAsync(dt.Rows.Cast<DataRow>().ToList(), Size, async item =>
                {
                    resul += await _BulkCopy(tableName, item.CopyToDataTable()).ConfigureAwait(false);
                }).ConfigureAwait(false);
                return resul;
            }
            else
            {
                return await _BulkCopy(tableName, dt).ConfigureAwait(false);
            }
        }
        /// <summary>批量插入实体列表</summary>
        public int BulkCopy(List<T> datas)
        {
            return BulkCopyAsync(datas).ConfigureAwait(true).GetAwaiter().GetResult();
        }
        /// <summary>异步批量插入实体列表</summary>
        public async Task<int> BulkCopyAsync(List<T> datas)
        {
            if (Size > 0)
            {
                if (this.GetBuider()?.DbFastestProperties?.NoPage == true)
                {
                    Size = int.MaxValue / 2;
                }
                int resul = 0;
                await context.Utilities.PageEachAsync(datas, Size, async item =>
                {
                    resul += await _BulkCopy(item).ConfigureAwait(false);
                }).ConfigureAwait(false);
                return resul;
            }
            else
            {
                return await _BulkCopy(datas).ConfigureAwait(false);
            }
        }
        #endregion

        #region BulkUpdate
        /// <summary>批量更新实体列表</summary>
        public int BulkUpdate(List<T> datas)
        {
            return BulkUpdateAsync(datas).ConfigureAwait(true).GetAwaiter().GetResult();
        }
        /// <summary>异步批量更新实体列表</summary>
        public async Task<int> BulkUpdateAsync(List<T> 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).ConfigureAwait(false);
        }
        /// <summary>批量更新实体列表</summary>
        public int BulkUpdate(List<T> 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();
        }

        /// <summary>批量更新实体列表</summary>
        public int BulkUpdate(List<T> datas, string[] whereColumns)
        {
            return BulkUpdateAsync(datas, whereColumns).GetAwaiter().GetResult();
        }

        /// <summary>异步批量更新实体列表</summary>
        public async Task<int> BulkUpdateAsync(List<T> 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);
        }
        /// <summary>异步批量更新实体列表</summary>
        public async Task<int> BulkUpdateAsync(List<T> datas, string[] whereColumns, string[] updateColumns)
        {

            if (Size > 0)
            {
                int resul = 0;
                await context.Utilities.PageEachAsync(datas, Size, async item =>
                {
                    resul += await _BulkUpdate(item, whereColumns, updateColumns).ConfigureAwait(false);
                }).ConfigureAwait(false);
                return resul;
            }
            else
            {
                return await _BulkUpdate(datas, whereColumns, updateColumns).ConfigureAwait(false);
            }
        }

        /// <summary>批量更新DataTable数据</summary>
        public int BulkUpdate(string tableName, DataTable dataTable, string[] whereColumns, string[] updateColumns)
        {
            return BulkUpdateAsync(tableName, dataTable, whereColumns, updateColumns).ConfigureAwait(true).GetAwaiter().GetResult();
        }
        /// <summary>批量更新DataTable数据</summary>
        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();
        }
        /// <summary>批量更新DataTable数据</summary>
        public int BulkUpdate(DataTable dataTable, string[] whereColumns)
        {
            string[] updateColumns = dataTable.Columns.Cast<DataColumn>().Select(it => it.ColumnName).Where(it => !whereColumns.Any(z => z.EqualCase(it))).ToArray();
            whereColumns = dataTable.Columns.Cast<DataColumn>().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();
        }
        /// <summary>异步批量更新DataTable数据</summary>
        public Task<int> BulkUpdateAsync(DataTable dataTable, string[] whereColumns)
        {
            string[] updateColumns = dataTable.Columns.Cast<DataColumn>().Select(it => it.ColumnName).Where(it => !whereColumns.Any(z => z.EqualCase(it))).ToArray();
            whereColumns = dataTable.Columns.Cast<DataColumn>().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);
        }
        /// <summary>异步批量更新DataTable数据</summary>
        public async Task<int> BulkUpdateAsync(string tableName, DataTable dataTable, string[] whereColumns, string[] updateColumns)
        {

            if (Size > 0)
            {
                int resul = 0;
                await context.Utilities.PageEachAsync(dataTable.Rows.Cast<DataRow>().ToList(), Size, async item =>
                {
                    resul += await _BulkUpdate(tableName, item.CopyToDataTable(), whereColumns, updateColumns).ConfigureAwait(false);
                }).ConfigureAwait(false);
                return resul;
            }
            else
            {
                return await _BulkUpdate(tableName, dataTable, whereColumns, updateColumns).ConfigureAwait(false);
            }
        }
        #endregion

        #region BulkMerge
        /// <summary>异步批量合并实体列表</summary>
        public Task<int> BulkMergeAsync(List<T> datas)
        {
            var updateColumns = entityInfo.Columns.Where(it => !it.IsPrimarykey && !it.IsIdentity && !it.IsOnlyIgnoreUpdate && !it.IsIgnore).Select(it => it.DbColumnName ?? it.PropertyName).ToArray();
            var whereColumns = entityInfo.Columns.Where(it => it.IsPrimarykey).Select(it => it.DbColumnName ?? it.PropertyName).ToArray(); ;
            return BulkMergeAsync(datas, whereColumns, updateColumns);
        }
        /// <summary>批量合并实体列表</summary>
        public int BulkMerge(List<T> datas)
        {
            return BulkMergeAsync(datas).GetAwaiter().GetResult();
        }
        /// <summary>批量合并DataTable数据</summary>
        public int BulkMerge(DataTable dataTable, string[] whereColumns, bool isIdentity)
        {
            object newValue, fastestMethod;
            MethodInfo bulkCopyMethod;
            _BulkMerge(dataTable, whereColumns, out newValue, out fastestMethod, out bulkCopyMethod, false, isIdentity);
            var result = (int)bulkCopyMethod.Invoke(fastestMethod, new object[] { newValue });
            return result;
        }
        /// <summary>异步批量合并DataTable数据</summary>
        public Task<int> BulkMergeAsync(DataTable dataTable, string[] whereColumns, bool isIdentity)
        {
            object newValue, fastestMethod;
            MethodInfo bulkCopyMethod;
            _BulkMerge(dataTable, whereColumns, out newValue, out fastestMethod, out bulkCopyMethod, true, isIdentity);
            var result = (Task<int>)bulkCopyMethod.Invoke(fastestMethod, new object[] { newValue });
            return result;
        }
        /// <summary>批量合并DataTable数据</summary>
        public int BulkMerge(DataTable dataTable, string[] whereColumns, string[] updateColumns, bool isIdentity)
        {
            return BulkMergeAsync(dataTable, whereColumns, updateColumns, isIdentity).GetAwaiter().GetResult();
        }
        /// <summary>异步批量合并DataTable数据</summary>
        public Task<int> BulkMergeAsync(DataTable dataTable, string[] whereColumns, string[] updateColumns, bool isIdentity)
        {
            object newValue, fastestMethod;
            MethodInfo bulkCopyMethod;
            _BulkMerge(dataTable, whereColumns, updateColumns, out newValue, out fastestMethod, out bulkCopyMethod, true, isIdentity);
            var result = (Task<int>)bulkCopyMethod.Invoke(fastestMethod, new object[] { newValue, whereColumns, updateColumns });
            return result;
        }
        /// <summary>异步批量合并实体列表</summary>
        public Task<int> BulkMergeAsync(List<T> datas, string[] whereColumns)
        {
            var updateColumns = entityInfo.Columns.Where(it => !it.IsPrimarykey && !it.IsIdentity && !it.IsOnlyIgnoreUpdate && !it.IsIgnore).Select(it => it.DbColumnName ?? it.PropertyName).ToArray();
            return BulkMergeAsync(datas, whereColumns, updateColumns);
        }
        /// <summary>批量合并实体列表</summary>
        public int BulkMerge(List<T> datas, string[] whereColumns)
        {
            return BulkMergeAsync(datas, whereColumns).GetAwaiter().GetResult();
        }
        /// <summary>异步批量合并实体列表</summary>
        public async Task<int> BulkMergeAsync(List<T> datas, string[] whereColumns, string[] updateColumns)
        {
            if (Size > 0)
            {
                int resul = 0;
                await context.Utilities.PageEachAsync(datas, Size, async item =>
                {
                    resul += await _BulkMerge(item, updateColumns, whereColumns).ConfigureAwait(false);
                }).ConfigureAwait(false);
                return resul;
            }
            else
            {
                return await _BulkMerge(datas, updateColumns, whereColumns).ConfigureAwait(false);
            }
        }
        /// <summary>批量合并实体列表</summary>
        public int BulkMerge(List<T> datas, string[] whereColumns, string[] updateColumns)
        {
            return BulkMergeAsync(datas, whereColumns, updateColumns).GetAwaiter().GetResult();
        }

        /// <summary>执行批量合并操作</summary>
        private async Task<int> _BulkMerge(List<T> datas, string[] updateColumns, string[] whereColumns)
        {
            try
            {
                Begin(datas, false, true);
                Check.Exception(whereColumns == null || whereColumns.Length == 0, "where columns count=0 or need primary key");
                Check.Exception(whereColumns == null || whereColumns.Length == 0, "where columns count=0 or need primary key");
                var isAuto = this.context.CurrentConnectionConfig.IsAutoCloseConnection;
                this.context.CurrentConnectionConfig.IsAutoCloseConnection = false;
                var old = this.context.Ado.IsDisableMasterSlaveSeparation;
                this.context.Ado.IsDisableMasterSlaveSeparation = true;
                DataTable dt = ToDdateTable(datas);
                IFastBuilder buider = GetBuider();
                buider.Context = context;
                if (buider?.DbFastestProperties?.IsMerge == true)
                {
                    await buider.CreateTempAsync<T>(dt).ConfigureAwait(false);
                    await buider.ExecuteBulkCopyAsync(dt).ConfigureAwait(false);
                }
                var result = await buider.Merge(GetTableName(), dt, entityInfo, whereColumns, updateColumns, datas).ConfigureAwait(false);
                //var queryTemp = this.context.Queryable<T>().AS(dt.TableName).ToList();//test
                //var result = await buider.UpdateByTempAsync(GetTableName(), dt.TableName, updateColumns, whereColumns);
                if (buider?.DbFastestProperties?.IsMerge == true && this.context.CurrentConnectionConfig.DbType != DbType.Sqlite)
                {
                    this.context.DbMaintenance.DropTable(dt.TableName);
                }
                this.context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto;
                buider.CloseDb();
                End(datas, false, true);
                this.context.Ado.IsDisableMasterSlaveSeparation = old;
                return result;
            }
            catch (Exception)
            {
                this.context.Close();
                throw;
            }
        }
        #endregion

        #region Core
        /// <summary>准备批量合并操作</summary>
        private void _BulkMerge(DataTable dataTable, string[] whereColumns, out object newValue, out object fastestMethod, out MethodInfo bulkCopyMethod, bool isAsync, bool isIdentity)
        {
            Check.ExceptionEasy(this.AsName.IsNullOrEmpty(), "need .AS(tablaeName) ", "需要 .AS(tablaeName) 设置表名");
            var className = "BulkMerge_" + isIdentity + this.AsName.GetNonNegativeHashCodeString();
            var builder = this.context.DynamicBuilder().CreateClass(className, new SugarTable()
            {
                TableName = this.AsName
            });
            foreach (DataColumn item in dataTable.Columns)
            {
                var isPrimaryKey = whereColumns.Any(it => it.EqualCase(item.ColumnName));
                var propertyType = item.DataType;
                if (!propertyType.IsClass() && propertyType != typeof(string) && propertyType != typeof(byte[]))
                {
                    propertyType = typeof(Nullable<>).MakeGenericType(UtilMethods.GetUnderType(item.DataType));
                }
                builder.CreateProperty(item.ColumnName, propertyType, new SugarColumn()
                {
                    IsPrimaryKey = isPrimaryKey,
                    IsIdentity = isIdentity && isPrimaryKey,
                    IsNullable = true,

                });
            }
            var dicList = this.context.Utilities.DataTableToDictionaryList(dataTable);
            var type = builder.WithCache().BuilderType();
            var value = this.context.DynamicBuilder().CreateObjectByType(type, dicList);
            newValue = UtilMethods.ConvertToObjectList(type, value);
            fastestMethod = this.context.GetType()
                                  .GetMethod("Fastest")
                                  .MakeGenericMethod(type)
                                  .Invoke(this.context, null);
            bulkCopyMethod = fastestMethod.GetType().GetMyMethod(isAsync ? "BulkMergeAsync" : "BulkMerge", 1);
        }
        /// <summary>准备批量合并操作</summary>
        private void _BulkMerge(DataTable dataTable, string[] whereColumns, string[] updateColumns, out object newValue, out object fastestMethod, out MethodInfo bulkCopyMethod, bool isAsync, bool isIdentity)
        {
            Check.ExceptionEasy(this.AsName.IsNullOrEmpty(), "need .AS(tablaeName) ", "需要 .AS(tablaeName) 设置表名");
            var className = "BulkMerge_" + isIdentity + this.AsName.GetNonNegativeHashCodeString();
            var builder = this.context.DynamicBuilder().CreateClass(className, new SugarTable()
            {
                TableName = this.AsName
            });
            foreach (DataColumn item in dataTable.Columns)
            {
                var isPrimaryKey = whereColumns.Any(it => it.EqualCase(item.ColumnName));
                var propertyType = item.DataType;
                if (!propertyType.IsClass() && propertyType != typeof(string) && propertyType != typeof(byte[]))
                {
                    propertyType = typeof(Nullable<>).MakeGenericType(UtilMethods.GetUnderType(item.DataType));
                }
                builder.CreateProperty(item.ColumnName, propertyType, new SugarColumn()
                {
                    IsPrimaryKey = isPrimaryKey,
                    IsIdentity = isIdentity && isPrimaryKey,
                    IsNullable = true,

                });
            }
            var dicList = this.context.Utilities.DataTableToDictionaryList(dataTable);
            var type = builder.WithCache().BuilderType();
            var value = this.context.DynamicBuilder().CreateObjectByType(type, dicList);
            newValue = UtilMethods.ConvertToObjectList(type, value);
            fastestMethod = this.context.GetType()
                                  .GetMethod("Fastest")
                                  .MakeGenericMethod(type)
                                  .Invoke(this.context, null);
            bulkCopyMethod = fastestMethod.GetType().GetMyMethod(isAsync ? "BulkMergeAsync" : "BulkMerge", 3, newValue.GetType(), typeof(string[]), typeof(string[]));
        }

        /// <summary>执行批量更新操作</summary>
        private async Task<int> _BulkUpdate(List<T> datas, string[] whereColumns, string[] updateColumns)
        {
            var isAuto = this.context.CurrentConnectionConfig.IsAutoCloseConnection;
            var isAutoOk = false;
            var old = this.context.Ado.IsDisableMasterSlaveSeparation;
            var oldOk = false;
            try
            {
                Begin(datas, false);
                Check.Exception(whereColumns == null || whereColumns.Length == 0, "where columns count=0 or need primary key");
                Check.Exception(updateColumns == null || updateColumns.Length == 0, "set columns count=0");
                this.context.CurrentConnectionConfig.IsAutoCloseConnection = false;
                this.context.Ado.IsDisableMasterSlaveSeparation = true;
                DataTable dt = ToDdateTable(datas);
                IFastBuilder buider = GetBuider();
                ActionIgnoreColumns(whereColumns, updateColumns, dt, buider.IsActionUpdateColumns);
                buider.Context = context;
                await buider.CreateTempAsync<T>(dt).ConfigureAwait(false);
                await buider.ExecuteBulkCopyAsync(dt).ConfigureAwait(false);
                //var queryTemp = this.context.Queryable<T>().AS(dt.TableName).ToList();//test
                var result = await buider.UpdateByTempAsync(GetTableName(), dt.TableName, updateColumns, whereColumns).ConfigureAwait(false);
                if (this.context.CurrentConnectionConfig.DbType != DbType.Sqlite)
                {
                    this.context.DbMaintenance.DropTable(dt.TableName);
                }
                this.context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto;
                isAutoOk = true;
                buider.CloseDb();
                this.context.Ado.IsDisableMasterSlaveSeparation = old;
                oldOk = true;
                End(datas, false);
                return result;
            }
            catch (Exception)
            {
                this.context.Close();
                throw;
            }
            finally
            {
                if (!isAutoOk)
                    this.context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto;
                if (!oldOk)
                    this.context.Ado.IsDisableMasterSlaveSeparation = old;
            }
        }

        /// <summary>处理忽略列</summary>
        private void ActionIgnoreColumns(string[] whereColumns, string[] updateColumns, DataTable dt, bool IsActionUpdateColumns)
        {
            if (entityInfo.Columns.Where(it => it.IsIgnore == false).Count() > whereColumns.Length + updateColumns.Length && IsActionUpdateColumns)
            {
                var ignoreColumns = dt.Columns.Cast<DataColumn>()
                .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 ignoreColumns)
                    {
                        if (item[col.ColumnName].IsNullOrEmpty())
                        {
                            if (col.DataType == UtilConstants.StringType)
                            {
                                item[col.ColumnName] = string.Empty;
                                if (this.queryable?.SqlBuilder?.SqlParameterKeyWord == ":")
                                {
                                    item[col.ColumnName] = " ";
                                }
                                ;
                            }
                            else if (col.DataType == UtilConstants.DateType)
                            {
                                item[col.ColumnName] = UtilMethods.GetMinDate(this.context.CurrentConnectionConfig);
                            }
                            else
                            {
                                item[col.ColumnName] = Activator.CreateInstance(col.DataType);
                            }
                        }
                    }
                }
            }
        }

        /// <summary>执行批量更新操作</summary>
        private async Task<int> _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.Length == 0, "where columns count=0 or need primary key");
            Check.Exception(updateColumns == null || updateColumns.Length == 0, "set columns count=0");
            var isAuto = this.context.CurrentConnectionConfig.IsAutoCloseConnection;
            this.context.CurrentConnectionConfig.IsAutoCloseConnection = false;
            var old = this.context.Ado.IsDisableMasterSlaveSeparation;
            this.context.Ado.IsDisableMasterSlaveSeparation = true;
            dataTable.TableName = this.queryable.SqlBuilder.GetTranslationTableName(tableName);
            DataTable dt = GetCopyWriteDataTableUpdate(dataTable);
            IFastBuilder buider = GetBuider();
            if (dt.Columns.Count != dataTable.Columns.Count)
            {
                ActionIgnoreColumns(whereColumns, updateColumns, dt, buider.IsActionUpdateColumns);
            }
            buider.Context = context;
            if (buider.DbFastestProperties == null)
            {
                buider.DbFastestProperties = new DbFastestProperties();
            }
            buider.DbFastestProperties.WhereColumns = whereColumns;
            await buider.CreateTempAsync<object>(dt).ConfigureAwait(false);
            await buider.ExecuteBulkCopyAsync(dt).ConfigureAwait(false);
            //var queryTemp = this.context.Queryable<T>().AS(dt.TableName).ToList();//test
            var result = await buider.UpdateByTempAsync(GetTableName(), dt.TableName, updateColumns, whereColumns).ConfigureAwait(false);
            if (this.context.CurrentConnectionConfig.DbType != DbType.Sqlite)
            {
                this.context.DbMaintenance.DropTable(dt.TableName);
            }
            this.context.CurrentConnectionConfig.IsAutoCloseConnection = isAuto;
            buider.CloseDb();
            this.context.Ado.IsDisableMasterSlaveSeparation = old;
            End(datas, false);
            return result;
        }
        /// <summary>执行批量插入操作</summary>
        private async Task<int> _BulkCopy(List<T> datas)
        {
            Begin(datas, true);
            DataTable dt = ToDdateTable(datas);
            IFastBuilder buider = GetBuider();
            buider.Context = context;
            var result = await buider.ExecuteBulkCopyAsync(dt).ConfigureAwait(false);
            End(datas, true);
            return result;
        }
        /// <summary>执行批量插入操作</summary>
        private async Task<int> _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).ConfigureAwait(false);
            End(datas, true);
            return result;
        }
        #endregion

        #region AOP
        /// <summary>结束操作</summary>
        private void End<Type>(List<Type> datas, bool isAdd, bool isMerge = false)
        {
            var title = isAdd ? "BulkCopy" : "BulkUpdate";
            if (isMerge)
            {
                title = "BulkMerge";
            }
            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}", Array.Empty<SugarParameter>());
            }
            RemoveCache();
        }
        /// <summary>开始操作</summary>
        private void Begin<Type>(List<Type> datas, bool isAdd, bool isMerge = false)
        {
            var title = isAdd ? "BulkCopy" : "BulkUpdate";
            if (isMerge)
            {
                title = "BulkMerge";
            }
            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} ", Array.Empty<SugarParameter>());
            }
            var dataEvent = this.context.CurrentConnectionConfig.AopEvents?.DataExecuting;
            if (IsDataAop && dataEvent != null)
            {
                var entity = this.context.EntityMaintenance.GetEntityInfo(typeof(Type));
                foreach (var item in datas)
                {
                    DataAop(item, isAdd
                                   ?
                                   DataFilterType.InsertByObject :
                                   DataFilterType.UpdateByObject
                                   , entity);
                }
            }
        }
        /// <summary>数据AOP处理</summary>
        private void DataAop<Type>(Type item, DataFilterType type, EntityInfo entity)
        {
            var dataEvent = this.context.CurrentConnectionConfig.AopEvents?.DataExecuting;
            if (dataEvent != null && item != null)
            {
                foreach (var columnInfo in entity.Columns)
                {
                    dataEvent(columnInfo.PropertyInfo.GetValue(item, null), new DataFilterModel() { OperationType = type, EntityValue = item, EntityColumnInfo = columnInfo });
                }
            }
        }
        #endregion

    }
}