コード例 #1
0
        public async Task ExecuteAsync_calls_Commit_if_no_transaction()
        {
            var mockModificationCommandBatch = new Mock <ModificationCommandBatch>();

            var transactionMock          = new Mock <RelationalTransaction>();
            var mockRelationalConnection = new Mock <IRelationalConnection>();

            RelationalTransaction currentTransaction = null;

            mockRelationalConnection.Setup(m => m.BeginTransaction()).Returns(() => currentTransaction = transactionMock.Object);
            mockRelationalConnection.Setup(m => m.Transaction).Returns(() => currentTransaction);

            var cancellationToken = new CancellationTokenSource().Token;

            var relationalTypeMapper = new RelationalTypeMapper();
            var batchExecutor        = new BatchExecutorForTest(relationalTypeMapper);

            await batchExecutor.ExecuteAsync(new[] { mockModificationCommandBatch.Object }, mockRelationalConnection.Object, cancellationToken);

            mockRelationalConnection.Verify(rc => rc.OpenAsync(cancellationToken));
            mockRelationalConnection.Verify(rc => rc.Close());
            transactionMock.Verify(t => t.Commit());
            mockModificationCommandBatch.Verify(mcb => mcb.ExecuteAsync(
                                                    It.IsAny <RelationalTransaction>(),
                                                    relationalTypeMapper,
                                                    It.IsAny <DbContext>(),
                                                    null,
                                                    cancellationToken));
        }
コード例 #2
0
    public void GetDbTransaction_returns_the_DbTransaction()
    {
        var dbConnection  = new FakeDbConnection(ConnectionString);
        var dbTransaction = new FakeDbTransaction(dbConnection);

        var connection = new FakeRelationalConnection(
            CreateOptions((FakeRelationalOptionsExtension) new FakeRelationalOptionsExtension().WithConnection(dbConnection)));

        var loggerFactory = new ListLoggerFactory();

        var transaction = new RelationalTransaction(
            connection,
            dbTransaction,
            new Guid(),
            new DiagnosticsLogger <DbLoggerCategory.Database.Transaction>(
                loggerFactory,
                new LoggingOptions(),
                new DiagnosticListener("Fake"),
                new TestRelationalLoggingDefinitions(),
                new NullDbContextLogger()),
            false,
            new RelationalSqlGenerationHelper(
                new RelationalSqlGenerationHelperDependencies()));

        Assert.Equal(dbTransaction, transaction.GetDbTransaction());
    }
コード例 #3
0
        public override int Execute(
            [NotNull] RelationalTransaction transaction,
            [NotNull] RelationalTypeMapper typeMapper,
            [NotNull] DbContext context,
            [NotNull] ILogger logger)
        {
            Check.NotNull(transaction, nameof(transaction));
            Check.NotNull(typeMapper, nameof(typeMapper));
            Check.NotNull(context, nameof(context));
            Check.NotNull(logger, nameof(logger));

            var commandText = GetCommandText();

            using (var storeCommand = CreateStoreCommand(commandText, transaction.DbTransaction, typeMapper, transaction.Connection?.CommandTimeout))
            {
                if (logger.IsEnabled(LogLevel.Verbose))
                {
                    // RelationalLoggerExtensions.LogCommand can't be called because the class
                    // is internal...
                    //logger.LogCommand(storeCommand);
                }

                try
                {
                    using (var reader = storeCommand.ExecuteReader())
                    {
                        var actualResultSetCount = 0;
                        do
                        {
                            actualResultSetCount++;
                        }while (reader.NextResult());

                        Debug.Assert(actualResultSetCount == ModificationCommands.Count, "Expected " + ModificationCommands.Count + " results, got " + actualResultSetCount);

                        if (reader.RecordsAffected != ModificationCommands.Count)
                        {
                            throw new DbUpdateConcurrencyException(
                                      Microsoft.Data.Entity.Relational.Strings.UpdateConcurrencyException(ModificationCommands.Count, reader.RecordsAffected),
                                      context,
                                      new List <InternalEntityEntry>() // TODO
                                      );
                        }
                    }
                }
                catch (DbUpdateException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    throw new DbUpdateException(
                              Microsoft.Data.Entity.Relational.Strings.UpdateStoreException,
                              context,
                              ex,
                              new InternalEntityEntry[0]);
                }
            }

            return(ModificationCommands.Count);
        }
コード例 #4
0
        public virtual async Task <int> ExecuteAsync(
            [NotNull] RelationalTransaction transaction,
            [NotNull] RelationalTypeMapper typeMapper,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            Check.NotNull(transaction, "transaction");
            Check.NotNull(typeMapper, "typeMapper");

            using (var storeCommand = CreateStoreCommand(transaction.DbTransaction, typeMapper))
            {
                var commandIndex = 0;
                try
                {
                    using (var reader = await storeCommand.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false))
                    {
                        do
                        {
                            var tableModification = ModificationCommands[commandIndex];

                            if (await reader.ReadAsync(cancellationToken).ConfigureAwait(false))
                            {
                                if (tableModification.RequiresResultPropagation)
                                {
                                    tableModification.PropagateResults(new RelationalTypedValueReader(reader));
                                }
                                else
                                {
                                    var rowsAffected = reader.GetFieldValue <int>(0);
                                    if (rowsAffected != 1)
                                    {
                                        throw new DbUpdateConcurrencyException(string.Format(Strings.FormatUpdateConcurrencyException(1, rowsAffected)), tableModification.StateEntries);
                                    }
                                }
                            }
                            else
                            {
                                throw new DbUpdateConcurrencyException(string.Format(Strings.FormatUpdateConcurrencyException(1, 0)), tableModification.StateEntries);
                            }

                            commandIndex++;
                        }while (await reader.NextResultAsync(cancellationToken).ConfigureAwait(false));
                    }
                }
                catch (DbUpdateException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    throw new DbUpdateException(
                              Strings.FormatUpdateStoreException(),
                              ex,
                              commandIndex < ModificationCommands.Count ? ModificationCommands[commandIndex].StateEntries : null);
                }
            }

            // TODO Return the actual results once we can get them
            return(1);
        }
コード例 #5
0
 public override Task <int> ExecuteAsync(
     [NotNull] RelationalTransaction transaction,
     [NotNull] RelationalTypeMapper typeMapper,
     [NotNull] DbContext context,
     [NotNull] ILogger logger,
     CancellationToken cancellationToken = default(CancellationToken))
 {
     throw new NotImplementedException("No async here yet");
 }
コード例 #6
0
        public virtual async Task <int> ExecuteAsync(
            [NotNull] IEnumerable <ModificationCommandBatch> commandBatches,
            [NotNull] RelationalConnection connection,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            Check.NotNull(commandBatches, "commandBatches");
            Check.NotNull(connection, "connection");

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

            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 : cancellationToken)
                                    .ConfigureAwait(false);
                }

                if (startedTransaction != null)
                {
                    startedTransaction.Commit();
                }
            }
            catch
            {
                if (connection.Transaction != null)
                {
                    connection.Transaction.Rollback();
                }

                throw;
            }
            finally
            {
                if (startedTransaction != null)
                {
                    startedTransaction.Dispose();
                }
                connection.Close();
            }

            return(rowsAffected);
        }
コード例 #7
0
ファイル: BatchExecutor.cs プロジェクト: Elidiomar/ef_core
        public virtual int Execute(
            [NotNull] IEnumerable <ModificationCommandBatch> commandBatches,
            [NotNull] RelationalConnection connection)
        {
            Check.NotNull(commandBatches, "commandBatches");
            Check.NotNull(connection, "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);
                }

                if (startedTransaction != null)
                {
                    startedTransaction.Commit();
                }
            }
            catch
            {
                if (connection.Transaction != null)
                {
                    connection.Transaction.Rollback();
                }

                throw;
            }
            finally
            {
                if (startedTransaction != null)
                {
                    startedTransaction.Dispose();
                }
                connection.Close();
            }

            return(rowsAffected);
        }
コード例 #8
0
        public void GetDbTransaction_returns_the_DbTransaction()
        {
            var dbConnection = new FakeDbConnection(ConnectionString);
            var dbTransaction = new FakeDbTransaction(dbConnection);

            var connection = new FakeRelationalConnection(
                CreateOptions(new FakeRelationalOptionsExtension { Connection = dbConnection }));

            var transaction = new RelationalTransaction(
                connection,
                dbTransaction,
                new ListLogger(new List<Tuple<LogLevel, string>>()),
                false);

            Assert.Equal(dbTransaction, transaction.GetDbTransaction());
        }
コード例 #9
0
        public static void ExplicitTransactionTwoSaveChanges()
        {
            CUI.MainHeadline(nameof(ExplicitTransactionTwoSaveChanges));
            using (var ctx = new WWWingsContext())
            {
                // Start transaction. Default is System.Data.IsolationLevel.ReadCommitted
                using (var t = ctx.Database.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
                {
                    // Print isolation level
                    RelationalTransaction rt  = t as RelationalTransaction;
                    DbTransaction         dbt = rt.GetDbTransaction();
                    Console.WriteLine("Transaction with Level: " + dbt.IsolationLevel);

                    // Read data
                    int flightNo = ctx.FlightSet.OrderBy(x => x.FlightNo).FirstOrDefault().FlightNo;
                    var f        = ctx.FlightSet.Where(x => x.FlightNo == flightNo).SingleOrDefault();

                    Console.WriteLine("Before: " + f.ToString());

                    // Change data and save
                    f.FreeSeats--;
                    var count1 = ctx.SaveChanges();
                    Console.WriteLine("Number of saved changes: " + count1);

                    //  Change data again and save
                    f.Memo = "last changed at " + DateTime.Now.ToString();
                    var count2 = ctx.SaveChanges();
                    Console.WriteLine("Number of saved changes: " + count2);

                    Console.WriteLine("Commit or Rollback? 1 = Commit, other = Rollback");
                    var eingabe = Console.ReadKey().Key;
                    if (eingabe == ConsoleKey.D1)
                    {
                        t.Commit(); Console.WriteLine("Commit done!");
                    }
                    else
                    {
                        t.Rollback(); Console.WriteLine("Rollback done!");
                    }

                    Console.WriteLine("After in RAM: " + f.ToString());
                    ctx.Entry(f).Reload();
                    Console.WriteLine("After in DB: " + f.ToString());
                }
            }
        }
コード例 #10
0
        public void GetDbTransaction_returns_the_DbTransaction()
        {
            var dbConnection  = new FakeDbConnection(ConnectionString);
            var dbTransaction = new FakeDbTransaction(dbConnection);

            var connection = new FakeRelationalConnection(
                CreateOptions((FakeRelationalOptionsExtension) new FakeRelationalOptionsExtension().WithConnection(dbConnection)));

            var transaction = new RelationalTransaction(
                connection,
                dbTransaction,
                new InterceptingLogger <LoggerCategory.Database.Transaction>(new ListLoggerFactory(new List <Tuple <LogLevel, string> >()), new LoggingOptions()),
                new DiagnosticListener("Fake"),
                false);

            Assert.Equal(dbTransaction, transaction.GetDbTransaction());
        }
コード例 #11
0
        public void GetDbTransaction_returns_the_DbTransaction()
        {
            var dbConnection  = new FakeDbConnection(ConnectionString);
            var dbTransaction = new FakeDbTransaction(dbConnection);

            var connection = new FakeRelationalConnection(
                CreateOptions(new FakeRelationalOptionsExtension {
                Connection = dbConnection
            }));

            var transaction = new RelationalTransaction(
                connection,
                dbTransaction,
                new ListLogger(new List <Tuple <LogLevel, string> >()),
                false);

            Assert.Equal(dbTransaction, transaction.GetDbTransaction());
        }
コード例 #12
0
        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);
        }
コード例 #13
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();
            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);
        }
コード例 #14
0
        protected virtual void ExecuteStatementsWithinTransaction(
            [NotNull] IEnumerable <SqlBatch> sqlStatements, [NotNull] RelationalConnection connection)
        {
            Check.NotNull(sqlStatements, "sqlStatements");
            Check.NotNull(connection, "connection");

            RelationalTransaction transaction = null;

            try
            {
                transaction = connection.BeginTransaction(IsolationLevel.Serializable);

                SqlExecutor.ExecuteNonQuery(connection, transaction.DbTransaction, sqlStatements);

                transaction.Commit();
            }
            finally
            {
                if (transaction != null)
                {
                    transaction.Dispose();
                }
            }
        }
コード例 #15
0
        public virtual IDbContextTransaction UseTransaction(DbTransaction transaction)
        {
            if (transaction == null)
            {
                if (CurrentTransaction != null)
                {
                    CurrentTransaction = null;

                    Close();
                }
            }
            else
            {
                if (CurrentTransaction != null)
                {
                    throw new InvalidOperationException(RelationalStrings.TransactionAlreadyStarted);
                }

                Open();

                CurrentTransaction = new RelationalTransaction(this, transaction, _logger, transactionOwned: false);
            }

            return CurrentTransaction;
        }
コード例 #16
0
        public override async Task <int> ExecuteAsync(
            RelationalTransaction transaction,
            RelationalTypeMapper typeMapper,
            DbContext context,
            ILogger logger,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            Check.NotNull(transaction, nameof(transaction));
            Check.NotNull(typeMapper, nameof(typeMapper));
            Check.NotNull(context, nameof(context));
            Check.NotNull(logger, nameof(logger));

            var commandText = GetCommandText();

            Debug.Assert(ResultSetEnds.Count == ModificationCommands.Count);

            var commandIndex = 0;

            using (var storeCommand = CreateStoreCommand(commandText, transaction.DbTransaction, typeMapper, transaction.Connection?.CommandTimeout))
            {
                if (logger.IsEnabled(LogLevel.Verbose))
                {
                    logger.LogCommand(storeCommand);
                }

                try
                {
                    using (var reader = await storeCommand.ExecuteReaderAsync(cancellationToken).WithCurrentCulture())
                    {
                        var actualResultSetCount = 0;
                        do
                        {
                            commandIndex = ModificationCommands[commandIndex].RequiresResultPropagation
                                ? await ConsumeResultSetWithPropagationAsync(commandIndex, reader, context, cancellationToken)
                                           .WithCurrentCulture()
                                : await ConsumeResultSetWithoutPropagationAsync(commandIndex, reader, context, cancellationToken)
                                           .WithCurrentCulture();

                            actualResultSetCount++;
                        }while (commandIndex < ResultSetEnds.Count &&
                                await reader.NextResultAsync(cancellationToken).WithCurrentCulture());

                        Debug.Assert(commandIndex == ModificationCommands.Count, "Expected " + ModificationCommands.Count + " results, got " + commandIndex);
#if DEBUG
                        var expectedResultSetCount = 1 + ResultSetEnds.Count(e => e);
                        expectedResultSetCount += ResultSetEnds[ResultSetEnds.Count - 1] ? -1 : 0;

                        Debug.Assert(actualResultSetCount == expectedResultSetCount, "Expected " + expectedResultSetCount + " result sets, got " + actualResultSetCount);
#endif
                    }
                }
                catch (DbUpdateException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    throw new DbUpdateException(
                              Strings.UpdateStoreException,
                              context,
                              ex,
                              commandIndex < ModificationCommands.Count ? ModificationCommands[commandIndex].Entries : new InternalEntityEntry[0]);
                }
            }

            return(commandIndex);
        }
コード例 #17
0
        public override async Task <int> ExecuteAsync(
            RelationalTransaction transaction,
            RelationalTypeMapper typeMapper,
            DbContext context,
            ILogger logger,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            Check.NotNull(transaction, "transaction");
            Check.NotNull(typeMapper, "typeMapper");
            Check.NotNull(context, "context");
            Check.NotNull(logger, "logger");

            if (logger.IsEnabled(TraceType.Verbose))
            {
                // TODO: Write parameter values
                logger.WriteSql(_sql);
            }

            var totalRowsAffected = 0;

            using (var storeCommand = CreateStoreCommand(transaction.DbTransaction, typeMapper))
            {
                var commandIndex = 0;
                try
                {
                    using (var reader = await storeCommand.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false))
                    {
                        do
                        {
                            var tableModification = ModificationCommands[commandIndex];

                            if (await reader.ReadAsync(cancellationToken).ConfigureAwait(false))
                            {
                                if (tableModification.RequiresResultPropagation)
                                {
                                    tableModification.PropagateResults(new RelationalTypedValueReader(reader));
                                    totalRowsAffected++;
                                }
                                else
                                {
                                    var rowsAffected = reader.GetFieldValue <int>(0);
                                    if (rowsAffected != 1)
                                    {
                                        throw new DbUpdateConcurrencyException(
                                                  Strings.FormatUpdateConcurrencyException(1, rowsAffected),
                                                  context,
                                                  tableModification.StateEntries);
                                    }
                                    totalRowsAffected += rowsAffected;
                                }
                            }
                            else
                            {
                                throw new DbUpdateConcurrencyException(
                                          Strings.FormatUpdateConcurrencyException(1, 0),
                                          context,
                                          tableModification.StateEntries);
                            }

                            commandIndex++;
                        }while (await reader.NextResultAsync(cancellationToken).ConfigureAwait(false));
                    }
                }
                catch (DbUpdateException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    throw new DbUpdateException(
                              Strings.FormatUpdateStoreException(),
                              context,
                              ex,
                              commandIndex < ModificationCommands.Count ? ModificationCommands[commandIndex].StateEntries : null);
                }
            }

            return(totalRowsAffected);
        }
コード例 #18
0
        private IDbContextTransaction BeginTransactionWithNoPreconditions(IsolationLevel isolationLevel)
        {
            Check.NotNull(_logger, nameof(_logger));

            _logger.LogDebug(
                RelationalLoggingEventId.BeginningTransaction,
                isolationLevel,
                il => RelationalStrings.RelationalLoggerBeginningTransaction(il.ToString("G")));

            CurrentTransaction
                = new RelationalTransaction(
                    this,
                    DbConnection.BeginTransaction(isolationLevel),
                    _logger,
                    transactionOwned: true);

            return CurrentTransaction;
        }
コード例 #19
0
 public abstract Task <int> ExecuteAsync(
     [NotNull] RelationalTransaction transaction,
     [NotNull] RelationalTypeMapper typeMapper,
     [NotNull] DbContext context,
     [NotNull] ILogger logger,
     CancellationToken cancellationToken = default(CancellationToken));
コード例 #20
0
        private RelationalTransaction BeginTransactionWithNoPreconditions(IsolationLevel isolationLevel)
        {
            Transaction = new RelationalTransaction(this, DbConnection.BeginTransaction(isolationLevel), transactionOwned: true);

            return Transaction;
        }
コード例 #21
0
 public abstract int Execute(
     [NotNull] RelationalTransaction transaction,
     [NotNull] RelationalTypeMapper typeMapper,
     [NotNull] DbContext context,
     [NotNull] ILogger logger);
コード例 #22
0
        public virtual RelationalTransaction UseTransaction([CanBeNull] DbTransaction transaction)
        {
            if (transaction == null)
            {
                if (Transaction != null)
                {
                    Transaction = null;

                    Close();
                }
            }
            else
            {
                if (Transaction != null)
                {
                    throw new InvalidOperationException(Strings.FormatTransactionAlreadyStarted());
                }

                Open();

                Transaction = new RelationalTransaction(this, transaction, transactionOwned: false);
            }

            return Transaction;
        }
コード例 #23
0
        public override int Execute(
            RelationalTransaction transaction,
            RelationalTypeMapper typeMapper,
            DbContext context,
            ILogger logger)
        {
            Check.NotNull(transaction, "transaction");
            Check.NotNull(typeMapper, "typeMapper");
            Check.NotNull(context, "context");
            Check.NotNull(logger, "logger");

            var commandText = GetCommandText();

            if (logger.IsEnabled(LogLevel.Verbose))
            {
                // TODO: Write parameter values
                logger.WriteSql(commandText);
            }

            Debug.Assert(ResultSetEnds.Count == ModificationCommands.Count);

            var commandIndex = 0;

            using (var storeCommand = CreateStoreCommand(commandText, transaction.DbTransaction, typeMapper, transaction.Connection?.CommandTimeout))
            {
                try
                {
                    using (var reader = storeCommand.ExecuteReader())
                    {
                        var actualResultSetCount = 0;
                        do
                        {
                            commandIndex = ModificationCommands[commandIndex].RequiresResultPropagation
                                ? ConsumeResultSetWithPropagation(commandIndex, reader, context)
                                : ConsumeResultSetWithoutPropagation(commandIndex, reader, context);
                            actualResultSetCount++;
                        }while (commandIndex < ResultSetEnds.Count &&
                                reader.NextResult());

                        Debug.Assert(commandIndex == ModificationCommands.Count, "Expected " + ModificationCommands.Count + " results, got " + commandIndex);
#if DEBUG
                        var expectedResultSetCount = 1 + ResultSetEnds.Count(e => e);
                        expectedResultSetCount += ResultSetEnds[ResultSetEnds.Count - 1] ? -1 : 0;

                        Debug.Assert(actualResultSetCount == expectedResultSetCount, "Expected " + expectedResultSetCount + " result sets, got " + actualResultSetCount);
#endif
                    }
                }
                catch (DbUpdateException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    throw new DbUpdateException(
                              Strings.UpdateStoreException,
                              context,
                              ex,
                              commandIndex < ModificationCommands.Count ? ModificationCommands[commandIndex].StateEntries : new StateEntry[0]);
                }
            }

            return(commandIndex);
        }
コード例 #24
0
        public override async Task<int> ExecuteAsync(
            RelationalTransaction transaction,
            RelationalTypeMapper typeMapper,
            DbContext context,
            ILogger logger,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            Check.NotNull(transaction, nameof(transaction));
            Check.NotNull(typeMapper, nameof(typeMapper));
            Check.NotNull(context, nameof(context));
            Check.NotNull(logger, nameof(logger));

            var commandText = GetCommandText();

            Debug.Assert(ResultSetEnds.Count == ModificationCommands.Count);

            var commandIndex = 0;
            using (var storeCommand = CreateStoreCommand(commandText, transaction.DbTransaction, typeMapper, transaction.Connection?.CommandTimeout))
            {
                if (logger.IsEnabled(LogLevel.Verbose))
                {
                    logger.LogCommand(storeCommand);
                }

                try
                {
                    using (var reader = await storeCommand.ExecuteReaderAsync(cancellationToken).WithCurrentCulture())
                    {
                        var actualResultSetCount = 0;
                        do
                        {
                            commandIndex = ModificationCommands[commandIndex].RequiresResultPropagation
                                ? await ConsumeResultSetWithPropagationAsync(commandIndex, reader, context, cancellationToken)
                                    .WithCurrentCulture()
                                : await ConsumeResultSetWithoutPropagationAsync(commandIndex, reader, context, cancellationToken)
                                    .WithCurrentCulture();
                            actualResultSetCount++;
                        }
                        while (commandIndex < ResultSetEnds.Count
                               && await reader.NextResultAsync(cancellationToken).WithCurrentCulture());

                        Debug.Assert(commandIndex == ModificationCommands.Count, "Expected " + ModificationCommands.Count + " results, got " + commandIndex);
#if DEBUG
                        var expectedResultSetCount = 1 + ResultSetEnds.Count(e => e);
                        expectedResultSetCount += ResultSetEnds[ResultSetEnds.Count - 1] ? -1 : 0;

                        Debug.Assert(actualResultSetCount == expectedResultSetCount, "Expected " + expectedResultSetCount + " result sets, got " + actualResultSetCount);
#endif
                    }
                }
                catch (DbUpdateException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    throw new DbUpdateException(
                        Strings.UpdateStoreException,
                        context,
                        ex,
                        commandIndex < ModificationCommands.Count ? ModificationCommands[commandIndex].Entries : new InternalEntityEntry[0]);
                }
            }

            return commandIndex;
        }
コード例 #25
0
        public override async Task <int> ExecuteAsync(
            RelationalTransaction transaction,
            RelationalTypeMapper typeMapper,
            DbContext context,
            ILogger logger,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            Check.NotNull(transaction, "transaction");
            Check.NotNull(typeMapper, "typeMapper");
            Check.NotNull(context, "context");
            Check.NotNull(logger, "logger");

            var commandText = GetCommandText();

            if (logger.IsEnabled(TraceType.Verbose))
            {
                // TODO: Write parameter values
                logger.WriteSql(commandText);
            }

            Contract.Assert(ResultSetEnds.Count == ModificationCommands.Count);

            var commandIndex = 0;

            using (var storeCommand = CreateStoreCommand(commandText, transaction.DbTransaction, typeMapper))
            {
                try
                {
                    using (var reader = await storeCommand.ExecuteReaderAsync(cancellationToken).WithCurrentCulture())
                    {
                        var actualResultSetCount = 0;
                        do
                        {
                            commandIndex = ModificationCommands[commandIndex].RequiresResultPropagation
                                ? await ConsumeResultSetWithPropagationAsync(commandIndex, reader, context, cancellationToken)
                                           .WithCurrentCulture()
                                : await ConsumeResultSetWithoutPropagationAsync(commandIndex, reader, context, cancellationToken)
                                           .WithCurrentCulture();

                            actualResultSetCount++;
                        }while (commandIndex < ResultSetEnds.Count &&
                                await reader.NextResultAsync(cancellationToken).WithCurrentCulture());

                        Contract.Assert(commandIndex == ModificationCommands.Count, "Expected " + ModificationCommands.Count + " results, got " + commandIndex);
#if DEBUG
                        var expectedResultSetCount = 1 + ResultSetEnds.Count(e => e);
                        expectedResultSetCount += ResultSetEnds[ResultSetEnds.Count - 1] ? -1 : 0;

                        Contract.Assert(actualResultSetCount == expectedResultSetCount, "Expected " + expectedResultSetCount + " result sets, got " + actualResultSetCount);
#endif
                    }
                }
                catch (DbUpdateException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    throw new DbUpdateException(
                              Strings.FormatUpdateStoreException(),
                              context,
                              ex,
                              commandIndex < ModificationCommands.Count ? ModificationCommands[commandIndex].StateEntries : new StateEntry[0]);
                }
            }

            return(commandIndex);
        }