public void Cloning_the_interception_context_preserves_contextual_information_but_not_mutable_state()
        {
            var objectContext = new ObjectContext();
            var dbContext     = DbContextMockHelper.CreateDbContext(objectContext);

            var interceptionContext = new EnlistTransactionInterceptionContext();

            interceptionContext.SuppressExecution();
            interceptionContext.Exception = new Exception("Cheez Whiz");

            var transaction = new CommittableTransaction();

            interceptionContext = interceptionContext
                                  .WithDbContext(dbContext)
                                  .WithObjectContext(objectContext)
                                  .WithTransaction(transaction)
                                  .AsAsync();

            Assert.Equal(new[] { objectContext }, interceptionContext.ObjectContexts);
            Assert.Equal(new[] { dbContext }, interceptionContext.DbContexts);
            Assert.True(interceptionContext.IsAsync);
            Assert.Same(transaction, interceptionContext.Transaction);

            Assert.Null(interceptionContext.Exception);
            Assert.Null(interceptionContext.OriginalException);
            Assert.False(interceptionContext.IsExecutionSuppressed);
        }
        public void Cloning_the_interception_context_preserves_contextual_information_but_not_mutable_state()
        {
            var objectContext = new ObjectContext();
            var dbContext = DbContextMockHelper.CreateDbContext(objectContext);

            var interceptionContext = new EnlistTransactionInterceptionContext();
            interceptionContext.SuppressExecution();
            interceptionContext.Exception = new Exception("Cheez Whiz");

            var transaction = new CommittableTransaction();
            interceptionContext = interceptionContext
                .WithDbContext(dbContext)
                .WithObjectContext(objectContext)
                .WithTransaction(transaction)
                .AsAsync();

            Assert.Equal(new[] { objectContext }, interceptionContext.ObjectContexts);
            Assert.Equal(new[] { dbContext }, interceptionContext.DbContexts);
            Assert.True(interceptionContext.IsAsync);
            Assert.Same(transaction, interceptionContext.Transaction);

            Assert.Null(interceptionContext.Exception);
            Assert.Null(interceptionContext.OriginalException);
            Assert.False(interceptionContext.IsExecutionSuppressed);
        }
Beispiel #3
0
        /// <summary>
        /// Creates a new <see cref="T:System.Data.Entity.Infrastructure.Interception.EnlistTransactionInterceptionContext" /> that contains all the contextual information in this
        /// interception context together with the given <see cref="P:System.Data.Entity.Infrastructure.Interception.EnlistTransactionInterceptionContext.Transaction" />.
        /// </summary>
        /// <param name="transaction">The transaction to be used in the <see cref="M:System.Data.Common.DbConnection.EnlistTransaction(System.Transactions.Transaction)" /> invocation.</param>
        /// <returns>A new interception context associated with the given isolation level.</returns>
        public EnlistTransactionInterceptionContext WithTransaction(
            Transaction transaction)
        {
            EnlistTransactionInterceptionContext interceptionContext = this.TypedClone();

            interceptionContext._transaction = transaction;
            return(interceptionContext);
        }
Beispiel #4
0
 /// <summary>
 /// Sends <see cref="M:System.Data.Entity.Infrastructure.Interception.IDbConnectionInterceptor.EnlistingTransaction(System.Data.Common.DbConnection,System.Data.Entity.Infrastructure.Interception.EnlistTransactionInterceptionContext)" /> and
 /// <see cref="M:System.Data.Entity.Infrastructure.Interception.IDbConnectionInterceptor.EnlistedTransaction(System.Data.Common.DbConnection,System.Data.Entity.Infrastructure.Interception.EnlistTransactionInterceptionContext)" /> to any <see cref="T:System.Data.Entity.Infrastructure.Interception.IDbConnectionInterceptor" />
 /// registered on <see cref="T:System.Data.Entity.Infrastructure.Interception.DbInterception" /> before/after making a
 /// call to <see cref="M:System.Data.Common.DbConnection.EnlistTransaction(System.Transactions.Transaction)" />.
 /// </summary>
 /// <param name="connection">The connection on which the operation will be executed.</param>
 /// <param name="interceptionContext">Optional information about the context of the call being made.</param>
 public virtual void EnlistTransaction(
     DbConnection connection,
     EnlistTransactionInterceptionContext interceptionContext)
 {
     Check.NotNull <DbConnection>(connection, nameof(connection));
     Check.NotNull <EnlistTransactionInterceptionContext>(interceptionContext, nameof(interceptionContext));
     this.InternalDispatcher.Dispatch <DbConnection, EnlistTransactionInterceptionContext>(connection, (Action <DbConnection, EnlistTransactionInterceptionContext>)((t, c) => t.EnlistTransaction(c.Transaction)), new EnlistTransactionInterceptionContext((DbInterceptionContext)interceptionContext), (Action <IDbConnectionInterceptor, DbConnection, EnlistTransactionInterceptionContext>)((i, t, c) => i.EnlistingTransaction(t, c)), (Action <IDbConnectionInterceptor, DbConnection, EnlistTransactionInterceptionContext>)((i, t, c) => i.EnlistedTransaction(t, c)));
 }
Beispiel #5
0
        /// <summary>
        /// Sends <see cref="IDbConnectionInterceptor.EnlistingTransaction" /> and
        /// <see cref="IDbConnectionInterceptor.EnlistedTransaction" /> to any <see cref="IDbConnectionInterceptor" />
        /// registered on <see cref="DbInterception" /> before/after making a
        /// call to <see cref="DbConnection.EnlistTransaction" />.
        /// </summary>
        /// <param name="connection">The connection on which the operation will be executed.</param>
        /// <param name="interceptionContext">Optional information about the context of the call being made.</param>
        public virtual void EnlistTransaction(DbConnection connection, EnlistTransactionInterceptionContext interceptionContext)
        {
            Check.NotNull(connection, "connection");
            Check.NotNull(interceptionContext, "interceptionContext");

            InternalDispatcher.Dispatch(
                connection,
                (t, c) => t.EnlistTransaction(c.Transaction),
                new EnlistTransactionInterceptionContext(interceptionContext),
                (i, t, c) => i.EnlistingTransaction(t, c),
                (i, t, c) => i.EnlistedTransaction(t, c));
        }
Beispiel #6
0
        /// <summary>
        /// Creates a new <see cref="T:System.Data.Entity.Infrastructure.Interception.EnlistTransactionInterceptionContext" /> by copying immutable state from the given
        /// interception context. Also see <see cref="M:System.Data.Entity.Infrastructure.Interception.EnlistTransactionInterceptionContext.Clone" />
        /// </summary>
        /// <param name="copyFrom">The context from which to copy state.</param>
        public EnlistTransactionInterceptionContext(DbInterceptionContext copyFrom)
            : base(copyFrom)
        {
            Check.NotNull <DbInterceptionContext>(copyFrom, nameof(copyFrom));
            EnlistTransactionInterceptionContext interceptionContext = copyFrom as EnlistTransactionInterceptionContext;

            if (interceptionContext == null)
            {
                return;
            }
            this._transaction = interceptionContext._transaction;
        }
Beispiel #7
0
        /// <summary>
        /// Sends <see cref="IDbConnectionInterceptor.EnlistingTransaction" /> and
        /// <see cref="IDbConnectionInterceptor.EnlistedTransaction" /> to any <see cref="IDbConnectionInterceptor" />
        /// registered on <see cref="DbInterception" /> before/after making a
        /// call to <see cref="DbConnection.EnlistTransaction" />.
        /// </summary>
        /// <param name="dbConnection">The connection on which the operation will be executed.</param>
        /// <param name="interceptionContext">Optional information about the context of the call being made.</param>
        public virtual void EnlistTransaction(DbConnection dbConnection, EnlistTransactionInterceptionContext interceptionContext)
        {
            Check.NotNull(dbConnection, "dbConnection");
            Check.NotNull(interceptionContext, "interceptionContext");

            var clonedInterceptionContext = new EnlistTransactionInterceptionContext(interceptionContext);

            InternalDispatcher.Dispatch(
                () => dbConnection.EnlistTransaction(clonedInterceptionContext.Transaction),
                clonedInterceptionContext,
                i => i.EnlistingTransaction(dbConnection, clonedInterceptionContext),
                i => i.EnlistedTransaction(dbConnection, clonedInterceptionContext));
        }
        public void Initially_has_no_state()
        {
            var interceptionContext = new EnlistTransactionInterceptionContext();

            Assert.Empty(interceptionContext.DbContexts);
            Assert.Null(interceptionContext.Exception);
            Assert.False(interceptionContext.IsAsync);
            Assert.False(interceptionContext.IsExecutionSuppressed);
            Assert.Null(interceptionContext.Transaction);
            Assert.Empty(interceptionContext.ObjectContexts);
            Assert.Null(interceptionContext.OriginalException);
            Assert.Equal((TaskStatus)0, interceptionContext.TaskStatus);
        }
        public void Initially_has_no_state()
        {
            var interceptionContext = new EnlistTransactionInterceptionContext();

            Assert.Empty(interceptionContext.DbContexts);
            Assert.Null(interceptionContext.Exception);
            Assert.False(interceptionContext.IsAsync);
            Assert.False(interceptionContext.IsExecutionSuppressed);
            Assert.Null(interceptionContext.Transaction);
            Assert.Empty(interceptionContext.ObjectContexts);
            Assert.Null(interceptionContext.OriginalException);
            Assert.Equal((TaskStatus)0, interceptionContext.TaskStatus);
        }
        public void EnlistTransaction_executes_operation_and_dispatches_to_interceptors()
        {
            var mockConnection = new Mock<DbConnection>();
            var mockInterceptor = new Mock<IDbConnectionInterceptor>();
            var dispatcher = new DbConnectionDispatcher();
            var internalDispatcher = dispatcher.InternalDispatcher;
            internalDispatcher.Add(mockInterceptor.Object);

            var transaction = new CommittableTransaction();
            var interceptionContext = new EnlistTransactionInterceptionContext().WithTransaction(transaction);
            dispatcher.EnlistTransaction(mockConnection.Object, interceptionContext);

            mockConnection.Verify(m => m.EnlistTransaction(transaction), Times.Once());
            mockInterceptor.Verify(m => m.EnlistingTransaction(mockConnection.Object, It.IsAny<EnlistTransactionInterceptionContext>()), Times.Once());
            mockInterceptor.Verify(m => m.EnlistedTransaction(mockConnection.Object, It.IsAny<EnlistTransactionInterceptionContext>()), Times.Once());
        }
        public void EnlistTransaction_executes_operation_and_dispatches_to_interceptors()
        {
            var mockConnection     = new Mock <DbConnection>();
            var mockInterceptor    = new Mock <IDbConnectionInterceptor>();
            var dispatcher         = new DbConnectionDispatcher();
            var internalDispatcher = dispatcher.InternalDispatcher;

            internalDispatcher.Add(mockInterceptor.Object);

            var transaction         = new CommittableTransaction();
            var interceptionContext = new EnlistTransactionInterceptionContext().WithTransaction(transaction);

            dispatcher.EnlistTransaction(mockConnection.Object, interceptionContext);

            mockConnection.Verify(m => m.EnlistTransaction(transaction), Times.Once());
            mockInterceptor.Verify(m => m.EnlistingTransaction(mockConnection.Object, It.IsAny <EnlistTransactionInterceptionContext>()), Times.Once());
            mockInterceptor.Verify(m => m.EnlistedTransaction(mockConnection.Object, It.IsAny <EnlistTransactionInterceptionContext>()), Times.Once());
        }
 public void EnlistedTransaction(DbConnection connection, EnlistTransactionInterceptionContext interceptionContext)
 {
 }
        /// <summary>
        /// Enlists this <see cref="T:System.Data.Entity.Core.EntityClient.EntityConnection" /> in the specified transaction.
        /// </summary>
        /// <param name="transaction">The transaction object to enlist into.</param>
        /// <exception cref="T:System.InvalidOperationException">
        /// The state of the <see cref="T:System.Data.Entity.Core.EntityClient.EntityConnection" /> is not
        /// <see
        ///     cref="F:System.Data.ConnectionState.Open" />
        /// .
        /// </exception>
        public override void EnlistTransaction(Transaction transaction)
        {
            if (_storeConnection == null)
            {
                throw Error.EntityClient_ConnectionStringNeededBeforeOperation();
            }

            if (State != ConnectionState.Open)
            {
                throw Error.EntityClient_ConnectionNotOpen();
            }

            try
            {
                var interceptionContext = new EnlistTransactionInterceptionContext(InterceptionContext);
                interceptionContext = interceptionContext.WithTransaction(transaction);

                DbInterception.Dispatch.Connection.EnlistTransaction(_storeConnection, interceptionContext);

                // null means "Unenlist transaction". It is fine if no transaction is in progress (no op). Otherwise
                // _storeConnection.EnlistTransaction should throw and we would not get here.
                Debug.Assert(
                    transaction != null || !EnlistedInUserTransaction,
                    "DbConnection should not allow unenlist from a transaction that has not completed.");

                // It is OK to enlist in null transaction or multiple times in the same transaction. 
                // In the latter case we don't need to be called multiple times when the transaction completes
                // so subscribe only when enlisting for the first time. Note that _storeConnection.EnlistTransaction
                // will throw in invalid cases (like enlisting the connection in a transaction when another
                // transaction has not completed) so when we get here we are sure that either no transactions are
                // active or the transaction the caller tries enlisting to 
                // is the active transaction.
                if (transaction != null
                    && !EnlistedInUserTransaction)
                {
                    transaction.TransactionCompleted += EnlistedTransactionCompleted;
                }

                _enlistedTransaction = transaction;
            }
            catch (Exception e)
            {
                if (e.IsCatchableExceptionType())
                {
                    throw new EntityException(Strings.EntityClient_ProviderSpecificError(@"EnlistTransaction"), e);
                }
                throw;
            }
        }
Beispiel #14
0
 /// <summary>
 /// Does not write to log unless overridden.
 /// </summary>
 /// <param name="connection">The connection.</param>
 /// <param name="interceptionContext">Contextual information associated with the call.</param>
 public virtual void EnlistedTransaction(DbConnection connection, EnlistTransactionInterceptionContext interceptionContext)
 {
 }
        /// <summary>
        /// Sends <see cref="IDbConnectionInterceptor.EnlistingTransaction" /> and
        /// <see cref="IDbConnectionInterceptor.EnlistedTransaction" /> to any <see cref="IDbConnectionInterceptor" />
        /// registered on <see cref="DbInterception" /> before/after making a
        /// call to <see cref="DbConnection.EnlistTransaction" />.
        /// </summary>
        /// <param name="connection">The connection on which the operation will be executed.</param>
        /// <param name="interceptionContext">Optional information about the context of the call being made.</param>
        public virtual void EnlistTransaction(DbConnection connection, EnlistTransactionInterceptionContext interceptionContext)
        {
            Check.NotNull(connection, "connection");
            Check.NotNull(interceptionContext, "interceptionContext");

            InternalDispatcher.Dispatch(
                connection,
                (t, c) => t.EnlistTransaction(c.Transaction),
                new EnlistTransactionInterceptionContext(interceptionContext),
                (i, t, c) => i.EnlistingTransaction(t, c),
                (i, t, c) => i.EnlistedTransaction(t, c));
        }
 /// <summary>
 /// 在数据库操作事务提交动作执行前瞬间触发。
 /// </summary>
 /// <param name="connection"></param>
 /// <param name="interceptionContext"></param>
 public virtual void EnlistingTransaction(DbConnection connection, EnlistTransactionInterceptionContext interceptionContext)
 {
 }
 public abstract void EnlistingTransaction(DbConnection connection, EnlistTransactionInterceptionContext interceptionContext);
 public abstract void EnlistedTransaction(DbConnection connection, EnlistTransactionInterceptionContext interceptionContext);