public virtual async Task<int> ExecuteAsync(
            IEnumerable<ModificationCommandBatch> commandBatches,
            IRelationalConnection connection,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            var rowsAffected = 0;
            await connection.OpenAsync(cancellationToken);
            IRelationalTransaction startedTransaction = null;
            try
            {
                if (connection.Transaction == null)
                {
                    startedTransaction = connection.BeginTransaction();
                }

                foreach (var commandbatch in commandBatches)
                {
                    await commandbatch.ExecuteAsync(connection, cancellationToken);
                    rowsAffected += commandbatch.ModificationCommands.Count;
                }

                startedTransaction?.Commit();
            }
            finally
            {
                startedTransaction?.Dispose();
                connection.Close();
            }

            return rowsAffected;
        }
Example #2
0
        public virtual int Execute(
            IEnumerable <ModificationCommandBatch> commandBatches,
            IRelationalConnection connection)
        {
            var rowsAffected = 0;

            connection.Open();
            IDbContextTransaction startedTransaction = null;

            try
            {
                if (connection.CurrentTransaction == null)
                {
                    startedTransaction = connection.BeginTransaction();
                }

                foreach (var commandbatch in commandBatches)
                {
                    commandbatch.Execute(connection);
                    rowsAffected += commandbatch.ModificationCommands.Count;
                }

                startedTransaction?.Commit();
            }
            finally
            {
                startedTransaction?.Dispose();
                connection.Close();
            }

            return(rowsAffected);
        }
        public virtual int Execute(
            IEnumerable<ModificationCommandBatch> commandBatches,
            IRelationalConnection connection)
        {
            var rowsAffected = 0;
            connection.Open();
            IRelationalTransaction startedTransaction = null;
            try
            {
                if (connection.Transaction == null)
                {
                    startedTransaction = connection.BeginTransaction();
                }

                foreach (var commandbatch in commandBatches)
                {
                    commandbatch.Execute(connection);
                    rowsAffected += commandbatch.ModificationCommands.Count;
                }

                startedTransaction?.Commit();
            }
            finally
            {
                startedTransaction?.Dispose();
                connection.Close();
            }

            return rowsAffected;
        }
Example #4
0
        public virtual async Task <int> ExecuteAsync(
            IEnumerable <ModificationCommandBatch> commandBatches,
            IRelationalConnection connection,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            var rowsAffected = 0;
            await connection.OpenAsync(cancellationToken);

            IDbContextTransaction startedTransaction = null;

            try
            {
                if (connection.CurrentTransaction == null)
                {
                    startedTransaction = connection.BeginTransaction();
                }

                foreach (var commandbatch in commandBatches)
                {
                    await commandbatch.ExecuteAsync(connection, cancellationToken);

                    rowsAffected += commandbatch.ModificationCommands.Count;
                }

                startedTransaction?.Commit();
            }
            finally
            {
                startedTransaction?.Dispose();
                connection.Close();
            }

            return(rowsAffected);
        }
Example #5
0
 private void Execute(IEnumerable <RelationalCommand> relationalCommands)
 {
     using (var transaction = _connection.BeginTransaction())
     {
         _executor.ExecuteNonQuery(_connection, relationalCommands);
         transaction.Commit();
     }
 }
Example #6
0
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        public virtual void ExecuteNonQuery(
            IEnumerable <MigrationCommand> migrationCommands,
            IRelationalConnection connection)
        {
            Check.NotNull(migrationCommands, nameof(migrationCommands));
            Check.NotNull(connection, nameof(connection));

            var userTransaction = connection.CurrentTransaction;

            if (userTransaction is not null && migrationCommands.Any(x => x.TransactionSuppressed))
            {
                throw new NotSupportedException(RelationalStrings.TransactionSuppressedMigrationInUserTransaction);
            }

            using (new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled))
            {
                connection.Open();

                try
                {
                    IDbContextTransaction?transaction = null;

                    try
                    {
                        foreach (var command in migrationCommands)
                        {
                            if (transaction == null &&
                                !command.TransactionSuppressed &&
                                userTransaction is null)
                            {
                                transaction = connection.BeginTransaction();
                            }

                            if (transaction != null &&
                                command.TransactionSuppressed)
                            {
                                transaction.Commit();
                                transaction.Dispose();
                                transaction = null;
                            }

                            command.ExecuteNonQuery(connection);
                        }

                        transaction?.Commit();
                    }
                    finally
                    {
                        transaction?.Dispose();
                    }
                }
                finally
                {
                    connection.Close();
                }
            }
        }
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        public virtual async Task <int> ExecuteAsync(
            IEnumerable <ModificationCommandBatch> commandBatches,
            IRelationalConnection connection,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            var rowsAffected = 0;
            await connection.OpenAsync(cancellationToken);

            IDbContextTransaction startedTransaction = null;

            try
            {
                if (connection.CurrentTransaction == null)
                {
                    startedTransaction = connection.BeginTransaction();
                }

                foreach (var commandbatch in commandBatches)
                {
                    await commandbatch.ExecuteAsync(connection, cancellationToken);

                    // Fixed Issue #1: DataReader conflicted when added multiple entities
                    try
                    {
                        lock (this)
                        {
                            var reader = (connection.DbConnection as MySqlConnection).Reader.LastOrDefault();
                            if (reader != null)
                            {
                                reader.Dispose();
                                (connection.DbConnection as MySqlConnection).Reader.Remove(reader);
                            }
                        }
                    }
                    catch
                    {
                    }
                    rowsAffected += commandbatch.ModificationCommands.Count;
                }

                startedTransaction?.Commit();
            }
            finally
            {
                startedTransaction?.Dispose();
                connection.Close();
            }

            return(rowsAffected);
        }
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        public virtual void ExecuteNonQuery(
            IEnumerable <MigrationCommand> migrationCommands,
            IRelationalConnection connection)
        {
            Check.NotNull(migrationCommands, nameof(migrationCommands));
            Check.NotNull(connection, nameof(connection));

            using (new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled))
            {
                connection.Open();

                try
                {
                    IDbContextTransaction transaction = null;

                    try
                    {
                        foreach (var command in migrationCommands)
                        {
                            if (transaction == null &&
                                !command.TransactionSuppressed)
                            {
                                transaction = connection.BeginTransaction();
                            }

                            if (transaction != null &&
                                command.TransactionSuppressed)
                            {
                                transaction.Commit();
                                transaction.Dispose();
                                transaction = null;
                            }

                            command.ExecuteNonQuery(connection);
                        }

                        transaction?.Commit();
                    }
                    finally
                    {
                        transaction?.Dispose();
                    }
                }
                finally
                {
                    connection.Close();
                }
            }
        }
Example #9
0
        protected virtual void Execute([NotNull] IEnumerable <SqlBatch> sqlBatches, bool ensureDatabase = false)
        {
            Check.NotNull(sqlBatches, nameof(sqlBatches));

            if (ensureDatabase && !_dataStoreCreator.Exists())
            {
                _dataStoreCreator.Create();
            }

            using (var transaction = _connection.BeginTransaction())
            {
                _executor.ExecuteNonQuery(_connection, transaction.DbTransaction, sqlBatches);
                transaction.Commit();
            }
        }
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used 
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        public virtual int Execute(
            IEnumerable<ModificationCommandBatch> commandBatches,
            IRelationalConnection connection)
        {
            var rowsAffected = 0;
            connection.Open();
            IDbContextTransaction startedTransaction = null;
            try
            {
                if (connection.CurrentTransaction == null)
                {
                    startedTransaction = connection.BeginTransaction();
                }

                foreach (var commandbatch in commandBatches)
                {
                    commandbatch.Execute(connection);
                    // Fixed Issue #1: DataReader conflicted when added multiple entities
                    try
                    {
                        lock (this)
                        {
                            var reader = (connection.DbConnection as MySqlConnection).Reader.LastOrDefault();
                            if (reader != null)
                            {
                                reader.Dispose();
                                (connection.DbConnection as MySqlConnection).Reader.Remove(reader);
                            }
                        }
                    }
                    catch
                    {
                    }
                    rowsAffected += commandbatch.ModificationCommands.Count;
                }

                startedTransaction?.Commit();
            }
            finally
            {
                startedTransaction?.Dispose();
                connection.Close();
            }

            return rowsAffected;
        }
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used 
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        public virtual void ExecuteNonQuery(
            IEnumerable<MigrationCommand> migrationCommands,
            IRelationalConnection connection)
        {
            Check.NotNull(migrationCommands, nameof(migrationCommands));
            Check.NotNull(connection, nameof(connection));

            connection.Open();

            try
            {
                IDbContextTransaction transaction = null;

                try
                {
                    foreach (var command in migrationCommands)
                    {
                        if (transaction == null
                            && !command.TransactionSuppressed)
                        {
                            transaction = connection.BeginTransaction();
                        }

                        if (transaction != null
                            && command.TransactionSuppressed)
                        {
                            transaction.Commit();
                            transaction.Dispose();
                            transaction = null;
                        }

                        command.ExecuteNonQuery(connection);
                    }

                    transaction?.Commit();
                }
                finally
                {
                    transaction?.Dispose();
                }
            }
            finally
            {
                connection.Close();
            }
        }
Example #12
0
        public int Execute(
            IEnumerable <ModificationCommandBatch> commandBatches,
            IRelationalConnection connection)
        {
            var registrosAfetados = 0;

            connection.Open();
            IDbContextTransaction startedTransaction = null;

            try
            {
                if (connection.CurrentTransaction == null)
                {
                    startedTransaction = connection.BeginTransaction();
                }


                foreach (var commandbatch in commandBatches)
                {
                    commandbatch.Execute(connection);
                    registrosAfetados += commandbatch.ModificationCommands.Count;
                }
                startedTransaction?.Commit();
                startedTransaction?.Dispose();
            }
            catch (Exception ex)
            {
                ex.Message.ToString();
                try
                {
                    startedTransaction?.Rollback();
                    startedTransaction?.Dispose();
                }
                catch
                {
                    // if the connection was lost, rollback command will fail.  prefer to throw original exception in that case
                }
                throw;
            }
            finally
            {
                connection.Close();
            }

            return(registrosAfetados);
        }
        public int Execute(IEnumerable <ModificationCommandBatch> commandBatches, IRelationalConnection connection)
        {
            var recordAffecteds = 0;

            if (connection?.DbConnection?.State != System.Data.ConnectionState.Open)
            {
                connection.Open();
            }

            IDbContextTransaction currentTransaction = null;

            try
            {
                if (connection.CurrentTransaction == null)
                {
                    currentTransaction = connection.BeginTransaction();
                }

                foreach (var commandbatch in commandBatches)
                {
                    commandbatch.Execute(connection);
                    recordAffecteds += commandbatch.ModificationCommands.Count;
                }
                currentTransaction?.Commit();
                currentTransaction?.Dispose();
            }
            catch (Exception ex)
            {
                try
                {
                    currentTransaction?.Rollback();
                    currentTransaction?.Dispose();
                }
                catch
                {
                    //
                }
                throw ex;
            }
            finally
            {
                connection?.Close();
            }
            return(recordAffecteds);
        }
Example #14
0
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        public virtual int Execute(
            IEnumerable <ModificationCommandBatch> commandBatches,
            IRelationalConnection connection)
        {
            var rowsAffected     = 0;
            var transaction      = connection.CurrentTransaction;
            var beganTransaction = false;
            var createdSavepoint = false;

            try
            {
                var transactionEnlistManager = connection as ITransactionEnlistmentManager;
                if (transaction == null &&
                    transactionEnlistManager?.EnlistedTransaction is null &&
                    transactionEnlistManager?.CurrentAmbientTransaction is null &&
                    CurrentContext.Context.Database.AutoTransactionsEnabled)
                {
                    transaction      = connection.BeginTransaction();
                    beganTransaction = true;
                }
                else
                {
                    connection.Open();

                    if (transaction?.SupportsSavepoints == true &&
                        CurrentContext.Context.Database.AutoSavepointsEnabled)
                    {
                        transaction.CreateSavepoint(SavepointName);
                        createdSavepoint = true;
                    }
                }

                foreach (var batch in commandBatches)
                {
                    batch.Execute(connection);
                    rowsAffected += batch.ModificationCommands.Count;
                }

                if (beganTransaction)
                {
                    transaction.Commit();
                }
            }
Example #15
0
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        public virtual int Execute(
            IEnumerable <ModificationCommandBatch> commandBatches,
            IRelationalConnection connection)
        {
            var rowsAffected = 0;
            IDbContextTransaction startedTransaction = null;

            try
            {
                if (connection.CurrentTransaction == null &&
                    (connection as ITransactionEnlistmentManager)?.EnlistedTransaction == null &&
                    Transaction.Current == null &&
                    CurrentContext.Context.Database.AutoTransactionsEnabled)
                {
                    startedTransaction = connection.BeginTransaction();
                }
                else
                {
                    connection.Open();
                }

                foreach (var batch in commandBatches)
                {
                    batch.Execute(connection);
                    rowsAffected += batch.ModificationCommands.Count;
                }

                startedTransaction?.Commit();
            }
            finally
            {
                if (startedTransaction != null)
                {
                    startedTransaction.Dispose();
                }
                else
                {
                    connection.Close();
                }
            }

            return(rowsAffected);
        }
        public virtual async Task <int> ExecuteAsync(
            [NotNull] IEnumerable <ModificationCommandBatch> commandBatches,
            [NotNull] IRelationalConnection connection,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            Check.NotNull(commandBatches, nameof(commandBatches));
            Check.NotNull(connection, nameof(connection));

            var rowsAffected = 0;
            await connection.OpenAsync(cancellationToken).WithCurrentCulture();

            RelationalTransaction startedTransaction = null;

            try
            {
                if (connection.Transaction == null)
                {
                    startedTransaction = connection.BeginTransaction();
                }

                foreach (var commandbatch in commandBatches)
                {
                    rowsAffected += await commandbatch.ExecuteAsync(
                        connection.Transaction,
                        _typeMapper,
                        _context,
                        Logger, cancellationToken)
                                    .WithCurrentCulture();
                }

                startedTransaction?.Commit();
            }
            finally
            {
                startedTransaction?.Dispose();
                connection.Close();
            }

            return(rowsAffected);
        }
Example #17
0
        public virtual int Execute(
            IEnumerable <ModificationCommandBatch> commandBatches,
            IRelationalConnection connection)
        {
            Check.NotNull(commandBatches, nameof(commandBatches));
            Check.NotNull(connection, nameof(connection));

            var rowsAffected = 0;

            connection.Open();
            IRelationalTransaction startedTransaction = null;

            try
            {
                if (connection.Transaction == null)
                {
                    startedTransaction = connection.BeginTransaction();
                }

                foreach (var commandbatch in commandBatches)
                {
                    commandbatch.Execute(
                        connection.Transaction,
                        _typeMapper,
                        _context,
                        Logger);
                    rowsAffected += commandbatch.ModificationCommands.Count;
                }

                startedTransaction?.Commit();
            }
            finally
            {
                startedTransaction?.Dispose();
                connection.Close();
            }

            return(rowsAffected);
        }
        public virtual int Execute(
            IEnumerable<ModificationCommandBatch> commandBatches,
            IRelationalConnection connection)
        {
            Check.NotNull(commandBatches, nameof(commandBatches));
            Check.NotNull(connection, nameof(connection));

            var rowsAffected = 0;
            connection.Open();
            RelationalTransaction startedTransaction = null;
            try
            {
                if (connection.Transaction == null)
                {
                    startedTransaction = connection.BeginTransaction();
                }

                foreach (var commandbatch in commandBatches)
                {
                    rowsAffected += commandbatch.Execute(
                        connection.Transaction,
                        _typeMapper,
                        _context,
                        Logger);
                }

                startedTransaction?.Commit();
            }
            finally
            {
                startedTransaction?.Dispose();
                connection.Close();
            }

            return rowsAffected;
        }
        /// <summary>
        /// 执行并返回一行一列的数据
        /// </summary>
        /// <param name="migrationCommands">迁移命令</param>
        /// <param name="connection">连接对象</param>
        /// <param name="logger">日志</param>
        /// <returns></returns>
        public object ExecuteScalar(
            IEnumerable <MigrationCommand> migrationCommands,
            IRelationalConnection connection,
            IDiagnosticsLogger <DbLoggerCategory.Database> logger = null)
        {
            try
            {
                if (Check.IsTraceEnabled(logger?.Logger))
                {
                    Trace <DbLoggerCategory.Database> .Write(logger, LogLevel.Trace, OracleTraceTag.Entry, OracleTraceClassName.OracleMigrationCommandExecutor, OracleTraceFuncName.ExecuteScalar);
                }

                m_oracleLogger = logger;
                object result = new object();
                Check.NotNull(migrationCommands, nameof(migrationCommands));
                Check.NotNull(connection, nameof(connection));
                using (new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled))
                {
                    connection.Open();
                    try
                    {
                        IDbContextTransaction dbContextTransaction = null;
                        try
                        {
                            foreach (MigrationCommand migrationCommand in migrationCommands)
                            {
                                if (dbContextTransaction == null && !migrationCommand.TransactionSuppressed)
                                {
                                    dbContextTransaction = connection.BeginTransaction();
                                }
                                if (dbContextTransaction != null && migrationCommand.TransactionSuppressed)
                                {
                                    dbContextTransaction.Commit();
                                    dbContextTransaction.Dispose();
                                    dbContextTransaction = null;
                                }
                                result = ((OracleMigrationCommand)migrationCommand).ExecuteScalar(connection);
                            }
                            dbContextTransaction?.Commit();
                        }
                        finally
                        {
                            dbContextTransaction?.Dispose();
                        }
                    }
                    finally
                    {
                        connection.Close();
                    }
                }
                return(result);
            }
            catch (Exception ex)
            {
                if (Check.IsErrorEnabled(logger?.Logger))
                {
                    Trace <DbLoggerCategory.Database> .Write(logger, LogLevel.Error, OracleTraceTag.Error, OracleTraceClassName.OracleMigrationCommandExecutor, OracleTraceFuncName.ExecuteScalar, ex.ToString());
                }
                throw;
            }
            finally
            {
                if (Check.IsTraceEnabled(logger?.Logger))
                {
                    Trace <DbLoggerCategory.Database> .Write(logger, LogLevel.Trace, OracleTraceTag.Exit, OracleTraceClassName.OracleMigrationCommandExecutor, OracleTraceFuncName.ExecuteScalar);
                }
            }
        }
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        public virtual int Execute(
            IEnumerable <ModificationCommandBatch> commandBatches,
            IRelationalConnection connection)
        {
            var rowsAffected     = 0;
            var transaction      = connection.CurrentTransaction;
            var beganTransaction = false;
            var createdSavepoint = false;

            try
            {
                if (transaction == null &&
                    (connection as ITransactionEnlistmentManager)?.EnlistedTransaction == null &&
                    Transaction.Current == null &&
                    CurrentContext.Context.Database.AutoTransactionsEnabled)
                {
                    transaction      = connection.BeginTransaction();
                    beganTransaction = true;
                }
                else
                {
                    connection.Open();

                    if (transaction?.AreSavepointsSupported == true)
                    {
                        transaction.Save(SavepointName);
                        createdSavepoint = true;
                    }
                }

                foreach (var batch in commandBatches)
                {
                    batch.Execute(connection);
                    rowsAffected += batch.ModificationCommands.Count;
                }

                if (beganTransaction)
                {
                    transaction.Commit();
                }
            }
            catch
            {
                if (createdSavepoint)
                {
                    transaction.Rollback(SavepointName);
                }

                throw;
            }
            finally
            {
                if (createdSavepoint)
                {
                    transaction.Release(SavepointName);
                }
                else if (beganTransaction)
                {
                    transaction.Dispose();
                }
                else
                {
                    connection.Close();
                }
            }

            return(rowsAffected);
        }
Example #21
0
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        public virtual int Execute(
            IEnumerable <ModificationCommandBatch> commandBatches,
            IRelationalConnection connection)
        {
            var rowsAffected     = 0;
            var transaction      = connection.CurrentTransaction;
            var beganTransaction = false;
            var createdSavepoint = false;

            try
            {
                if (transaction == null &&
                    (connection as ITransactionEnlistmentManager)?.EnlistedTransaction == null &&
                    Transaction.Current == null &&
                    CurrentContext.Context.Database.AutoTransactionsEnabled)
                {
                    transaction      = connection.BeginTransaction();
                    beganTransaction = true;
                }
                else
                {
                    connection.Open();

                    if (transaction?.SupportsSavepoints == true &&
                        CurrentContext.Context.Database.AutoSavepointsEnabled)
                    {
                        transaction.CreateSavepoint(SavepointName);
                        createdSavepoint = true;
                    }
                }

                foreach (var batch in commandBatches)
                {
                    batch.Execute(connection);
                    rowsAffected += batch.ModificationCommands.Count;
                }

                if (beganTransaction)
                {
                    transaction.Commit();
                }
            }
            catch
            {
                if (createdSavepoint && connection.DbConnection.State == ConnectionState.Open)
                {
                    try
                    {
                        transaction.RollbackToSavepoint(SavepointName);
                    }
                    catch (Exception e)
                    {
                        UpdateLogger.BatchExecutorFailedToRollbackToSavepoint(CurrentContext.GetType(), e);
                    }
                }

                throw;
            }
            finally
            {
                if (beganTransaction)
                {
                    transaction.Dispose();
                }
                else
                {
                    if (createdSavepoint)
                    {
                        if (connection.DbConnection.State == ConnectionState.Open)
                        {
                            try
                            {
                                transaction.ReleaseSavepoint(SavepointName);
                            }
                            catch (Exception e)
                            {
                                UpdateLogger.BatchExecutorFailedToReleaseSavepoint(CurrentContext.GetType(), e);
                            }
                        }
                    }

                    connection.Close();
                }
            }

            return(rowsAffected);
        }
        /// <summary>
        /// 执行
        /// </summary>
        /// <param name="migrationCommands">迁移命令</param>
        /// <param name="connection">连接对象</param>
        /// <param name="logger">日志</param>
        public void ExecuteNonQuery(
            IEnumerable <MigrationCommand> migrationCommands,
            IRelationalConnection connection,
            IDiagnosticsLogger <DbLoggerCategory.Database> logger = null)
        {
            try
            {
                if (Check.IsTraceEnabled(logger?.Logger))
                {
                    Trace <DbLoggerCategory.Database> .Write(logger, LogLevel.Trace, OracleTraceTag.Entry, OracleTraceClassName.OracleMigrationCommandExecutor, OracleTraceFuncName.ExecuteNonQuery);
                }

                m_oracleLogger = logger;
                Check.NotNull(migrationCommands, nameof(migrationCommands));
                Check.NotNull(connection, nameof(connection));
                using (new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled))
                {
                    connection.Open();
                    try
                    {
                        IDbContextTransaction dbContextTransaction = null;
                        try
                        {
                            foreach (MigrationCommand migrationCommand in migrationCommands)
                            {
                                if (dbContextTransaction == null && !migrationCommand.TransactionSuppressed)
                                {
                                    dbContextTransaction = connection.BeginTransaction();
                                }
                                if (dbContextTransaction != null && migrationCommand.TransactionSuppressed)
                                {
                                    dbContextTransaction.Commit();
                                    dbContextTransaction.Dispose();
                                    dbContextTransaction = null;
                                }
                                try
                                {
                                    migrationCommand.ExecuteNonQuery(connection);
                                }
                                catch (Exception ex)
                                {
                                    if (!migrationCommand.CommandText.StartsWith("CREATE UNIQUE INDEX") || (!ex.Message.Contains("ORA-01408") && !ex.Message.Contains("ORA-00955")))
                                    {
                                        throw;
                                    }
                                }
                            }
                            dbContextTransaction?.Commit();
                        }
                        finally
                        {
                            dbContextTransaction?.Dispose();
                        }
                    }
                    finally
                    {
                        connection.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                if (Check.IsErrorEnabled(logger?.Logger))
                {
                    Trace <DbLoggerCategory.Database> .Write(m_oracleLogger, LogLevel.Error, OracleTraceTag.Error, OracleTraceClassName.OracleMigrationCommandExecutor, OracleTraceFuncName.ExecuteNonQuery, ex.ToString());
                }
                throw;
            }
            finally
            {
                if (Check.IsTraceEnabled(logger?.Logger))
                {
                    Trace <DbLoggerCategory.Database> .Write(m_oracleLogger, LogLevel.Trace, OracleTraceTag.Exit, OracleTraceClassName.OracleMigrationCommandExecutor, OracleTraceFuncName.ExecuteNonQuery);
                }
            }
        }
        public virtual async Task<int> ExecuteAsync(
            IEnumerable<ModificationCommandBatch> commandBatches,
            IRelationalConnection connection,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            Check.NotNull(commandBatches, nameof(commandBatches));
            Check.NotNull(connection, nameof(connection));

            var rowsAffected = 0;
            await connection.OpenAsync(cancellationToken);
            RelationalTransaction startedTransaction = null;
            try
            {
                if (connection.Transaction == null)
                {
                    startedTransaction = connection.BeginTransaction();
                }

                foreach (var commandbatch in commandBatches)
                {
                    rowsAffected += await commandbatch.ExecuteAsync(
                        connection.Transaction,
                        _typeMapper,
                        _context,
                        Logger, cancellationToken);
                }

                startedTransaction?.Commit();
            }
            finally
            {
                startedTransaction?.Dispose();
                connection.Close();
            }

            return rowsAffected;
        }