diff --git a/src/EFCore.Relational/Diagnostics/DbConnectionInterceptor.cs b/src/EFCore.Relational/Diagnostics/DbConnectionInterceptor.cs index 0862c3422ec..17d95f5a0b8 100644 --- a/src/EFCore.Relational/Diagnostics/DbConnectionInterceptor.cs +++ b/src/EFCore.Relational/Diagnostics/DbConnectionInterceptor.cs @@ -119,7 +119,6 @@ public virtual Task ConnectionOpenedAsync( /// its implementation of this method. /// This value is typically used as the return value for the implementation of this method. /// - /// The cancellation token. /// /// If the result is null, then EF will close the connection as normal. /// If the result is non-null value, then connection closing is suppressed. @@ -129,8 +128,7 @@ public virtual Task ConnectionOpenedAsync( public virtual Task ConnectionClosingAsync( DbConnection connection, ConnectionEventData eventData, - InterceptionResult? result, - CancellationToken cancellationToken = default) + InterceptionResult? result) => Task.FromResult(result); /// @@ -149,12 +147,10 @@ public virtual void ConnectionClosed( /// /// The connection. /// Contextual information about the connection. - /// The cancellation token. /// A representing the asynchronous operation. public virtual Task ConnectionClosedAsync( DbConnection connection, - ConnectionEndEventData eventData, - CancellationToken cancellationToken = default) + ConnectionEndEventData eventData) => Task.CompletedTask; /// diff --git a/src/EFCore.Relational/Diagnostics/IDbConnectionInterceptor.cs b/src/EFCore.Relational/Diagnostics/IDbConnectionInterceptor.cs index 0a8106fd93e..203613290ce 100644 --- a/src/EFCore.Relational/Diagnostics/IDbConnectionInterceptor.cs +++ b/src/EFCore.Relational/Diagnostics/IDbConnectionInterceptor.cs @@ -131,7 +131,6 @@ Task ConnectionOpenedAsync( /// its implementation of this method. /// This value is typically used as the return value for the implementation of this method. /// - /// The cancellation token. /// /// If the result is null, then EF will close the connection as normal. /// If the result is non-null value, then connection closing is suppressed. @@ -141,8 +140,7 @@ Task ConnectionOpenedAsync( Task ConnectionClosingAsync( [NotNull] DbConnection connection, [NotNull] ConnectionEventData eventData, - InterceptionResult? result, - CancellationToken cancellationToken = default); + InterceptionResult? result); /// /// Called just after EF has called in an async context. @@ -158,12 +156,10 @@ void ConnectionClosed( /// /// The connection. /// Contextual information about the connection. - /// The cancellation token. /// A representing the asynchronous operation. Task ConnectionClosedAsync( [NotNull] DbConnection connection, - [NotNull] ConnectionEndEventData eventData, - CancellationToken cancellationToken = default); + [NotNull] ConnectionEndEventData eventData); /// /// Called when closing of a connection has failed with an exception. />. diff --git a/src/EFCore.Relational/Diagnostics/Internal/DbConnectionInterceptorResolver.cs b/src/EFCore.Relational/Diagnostics/Internal/DbConnectionInterceptorResolver.cs index 2b11c609fe0..0df476dbb68 100644 --- a/src/EFCore.Relational/Diagnostics/Internal/DbConnectionInterceptorResolver.cs +++ b/src/EFCore.Relational/Diagnostics/Internal/DbConnectionInterceptorResolver.cs @@ -100,12 +100,11 @@ public async Task ConnectionOpenedAsync( public async Task ConnectionClosingAsync( DbConnection connection, ConnectionEventData eventData, - InterceptionResult? result, - CancellationToken cancellationToken = default) + InterceptionResult? result) { for (var i = 0; i < _interceptors.Length; i++) { - result = await _interceptors[i].ConnectionClosingAsync(connection, eventData, result, cancellationToken); + result = await _interceptors[i].ConnectionClosingAsync(connection, eventData, result); } return result; @@ -123,12 +122,11 @@ public void ConnectionClosed( public async Task ConnectionClosedAsync( DbConnection connection, - ConnectionEndEventData eventData, - CancellationToken cancellationToken = default) + ConnectionEndEventData eventData) { for (var i = 0; i < _interceptors.Length; i++) { - await _interceptors[i].ConnectionClosedAsync(connection, eventData, cancellationToken); + await _interceptors[i].ConnectionClosedAsync(connection, eventData); } } diff --git a/src/EFCore.Relational/Diagnostics/RelationalLoggerExtensions.cs b/src/EFCore.Relational/Diagnostics/RelationalLoggerExtensions.cs index 0ff070e2cd7..d9f7cd5b044 100644 --- a/src/EFCore.Relational/Diagnostics/RelationalLoggerExtensions.cs +++ b/src/EFCore.Relational/Diagnostics/RelationalLoggerExtensions.cs @@ -1290,13 +1290,11 @@ private static string ConnectionOpened(EventDefinitionBase definition, EventData /// The diagnostics logger to use. /// The connection. /// The time that the operation was started. - /// The cancellation token. /// A representing the async operation. public static Task ConnectionClosingAsync( [NotNull] this IDiagnosticsLogger diagnostics, [NotNull] IRelationalConnection connection, - DateTimeOffset startTime, - CancellationToken cancellationToken = default) + DateTimeOffset startTime) { var definition = RelationalResources.LogClosingConnection(diagnostics); @@ -1318,7 +1316,7 @@ private static string ConnectionOpened(EventDefinitionBase definition, EventData if (interceptor != null) { - return interceptor.ConnectionClosingAsync(connection.DbConnection, eventData, null, cancellationToken); + return interceptor.ConnectionClosingAsync(connection.DbConnection, eventData, null); } } @@ -1417,14 +1415,12 @@ public static void ConnectionClosed( /// The connection. /// The time that the operation was started. /// The amount of time before the connection was closed. - /// The cancellation token. /// A representing the async operation. public static Task ConnectionClosedAsync( [NotNull] this IDiagnosticsLogger diagnostics, [NotNull] IRelationalConnection connection, DateTimeOffset startTime, - TimeSpan duration, - CancellationToken cancellationToken = default) + TimeSpan duration) { var definition = RelationalResources.LogClosedConnection(diagnostics); @@ -1447,7 +1443,7 @@ public static Task ConnectionClosedAsync( if (interceptor != null) { - return interceptor.ConnectionClosedAsync(connection.DbConnection, eventData, cancellationToken); + return interceptor.ConnectionClosedAsync(connection.DbConnection, eventData); } } diff --git a/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs b/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs index 2e2573b6088..90698e79562 100644 --- a/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs @@ -703,10 +703,9 @@ public static void CloseConnection([NotNull] this DatabaseFacade databaseFacade) /// Closes the underlying . /// /// The for the context. - /// A to observe while waiting for the task to complete. /// A task that represents the asynchronous operation. - public static Task CloseConnectionAsync([NotNull] this DatabaseFacade databaseFacade, CancellationToken cancellationToken = default) - => GetFacadeDependencies(databaseFacade).RelationalConnection.CloseAsync(cancellationToken); + public static Task CloseConnectionAsync([NotNull] this DatabaseFacade databaseFacade) + => GetFacadeDependencies(databaseFacade).RelationalConnection.CloseAsync(); /// /// Starts a new transaction with a given . diff --git a/src/EFCore.Relational/Migrations/Internal/MigrationCommandExecutor.cs b/src/EFCore.Relational/Migrations/Internal/MigrationCommandExecutor.cs index 9fd2b821e3d..d179d8d6611 100644 --- a/src/EFCore.Relational/Migrations/Internal/MigrationCommandExecutor.cs +++ b/src/EFCore.Relational/Migrations/Internal/MigrationCommandExecutor.cs @@ -139,7 +139,7 @@ public virtual async Task ExecuteNonQueryAsync( } finally { - await connection.CloseAsync(cancellationToken); + await connection.CloseAsync(); } } finally diff --git a/src/EFCore.Relational/Storage/IRelationalConnection.cs b/src/EFCore.Relational/Storage/IRelationalConnection.cs index 635af81fb62..db9a77f7a1d 100644 --- a/src/EFCore.Relational/Storage/IRelationalConnection.cs +++ b/src/EFCore.Relational/Storage/IRelationalConnection.cs @@ -80,14 +80,11 @@ public interface IRelationalConnection : IRelationalTransactionManager, IDisposa /// /// Closes the connection to the database. /// - /// - /// A to observe while waiting for the task to complete. - /// /// /// A task that represents the asynchronous operation, with a value of true if the connection /// was actually closed. /// - Task CloseAsync(CancellationToken cancellationToken = default); + Task CloseAsync(); /// /// Gets a value indicating whether the multiple active result sets feature is enabled. diff --git a/src/EFCore.Relational/Storage/RelationalCommand.cs b/src/EFCore.Relational/Storage/RelationalCommand.cs index b0fd37f9c96..daa37af082b 100644 --- a/src/EFCore.Relational/Storage/RelationalCommand.cs +++ b/src/EFCore.Relational/Storage/RelationalCommand.cs @@ -133,12 +133,11 @@ private static void CleanupCommand( private static async Task CleanupCommandAsync( DbCommand command, - IRelationalConnection connection, - CancellationToken cancellationToken = default) + IRelationalConnection connection) { command.Parameters.Clear(); await command.DisposeAsyncIfAvailable(); - await connection.CloseAsync(cancellationToken); + await connection.CloseAsync(); } /// @@ -214,7 +213,7 @@ await logger.CommandErrorAsync( } finally { - await CleanupCommandAsync(command, connection, cancellationToken); + await CleanupCommandAsync(command, connection); } } @@ -347,7 +346,7 @@ await logger.CommandErrorAsync( } finally { - await CleanupCommandAsync(command, connection, cancellationToken); + await CleanupCommandAsync(command, connection); } } @@ -510,7 +509,7 @@ await logger.CommandErrorAsync( { if (!readerOpen) { - await CleanupCommandAsync(command, connection, cancellationToken); + await CleanupCommandAsync(command, connection); } } } diff --git a/src/EFCore.Relational/Storage/RelationalConnection.cs b/src/EFCore.Relational/Storage/RelationalConnection.cs index 19e76f9831c..6af11f9ccca 100644 --- a/src/EFCore.Relational/Storage/RelationalConnection.cs +++ b/src/EFCore.Relational/Storage/RelationalConnection.cs @@ -655,14 +655,11 @@ public virtual bool Close() /// /// Closes the connection to the database. /// - /// - /// A to observe while waiting for the task to complete. - /// /// /// A task that represents the asynchronous operation, with a value of true if the connection /// was actually closed. /// - public virtual async Task CloseAsync(CancellationToken cancellationToken = default) + public virtual async Task CloseAsync() { var wasClosed = false; @@ -681,8 +678,7 @@ public virtual async Task CloseAsync(CancellationToken cancellationToken = var interceptionResult = await Dependencies.ConnectionLogger.ConnectionClosingAsync( this, - startTime, - cancellationToken); + startTime); try { @@ -696,8 +692,7 @@ public virtual async Task CloseAsync(CancellationToken cancellationToken = await Dependencies.ConnectionLogger.ConnectionClosedAsync( this, startTime, - stopwatch.Elapsed, - cancellationToken); + stopwatch.Elapsed); } catch (Exception e) { @@ -706,8 +701,7 @@ await Dependencies.ConnectionLogger.ConnectionErrorAsync( e, startTime, stopwatch.Elapsed, - false, - cancellationToken); + false); throw; } diff --git a/src/EFCore.Relational/Storage/RelationalTransaction.cs b/src/EFCore.Relational/Storage/RelationalTransaction.cs index 6111bebd4f9..043e2a597b7 100644 --- a/src/EFCore.Relational/Storage/RelationalTransaction.cs +++ b/src/EFCore.Relational/Storage/RelationalTransaction.cs @@ -349,7 +349,7 @@ protected virtual async Task ClearTransactionAsync(CancellationToken cancellatio { _connectionClosed = true; - await Connection.CloseAsync(cancellationToken); + await Connection.CloseAsync(); } } diff --git a/src/EFCore.Relational/Update/Internal/BatchExecutor.cs b/src/EFCore.Relational/Update/Internal/BatchExecutor.cs index 4a4a0cb251a..4245a2446e3 100644 --- a/src/EFCore.Relational/Update/Internal/BatchExecutor.cs +++ b/src/EFCore.Relational/Update/Internal/BatchExecutor.cs @@ -165,7 +165,7 @@ private async Task ExecuteAsync( } else { - await connection.CloseAsync(cancellationToken); + await connection.CloseAsync(); } } diff --git a/test/EFCore.Relational.Specification.Tests/ConnectionInterceptionTestBase.cs b/test/EFCore.Relational.Specification.Tests/ConnectionInterceptionTestBase.cs index a9baea36923..94de4e52ede 100644 --- a/test/EFCore.Relational.Specification.Tests/ConnectionInterceptionTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/ConnectionInterceptionTestBase.cs @@ -346,8 +346,7 @@ public virtual Task ConnectionOpenedAsync( public virtual Task ConnectionClosingAsync( DbConnection connection, ConnectionEventData eventData, - InterceptionResult? result, - CancellationToken cancellationToken = default) + InterceptionResult? result) { Assert.True(eventData.IsAsync); AsyncCalled = true; @@ -367,8 +366,7 @@ public virtual void ConnectionClosed( public virtual Task ConnectionClosedAsync( DbConnection connection, - ConnectionEndEventData eventData, - CancellationToken cancellationToken = default) + ConnectionEndEventData eventData) { Assert.True(eventData.IsAsync); AsyncCalled = true; diff --git a/test/EFCore.Relational.Tests/RelationalEventIdTest.cs b/test/EFCore.Relational.Tests/RelationalEventIdTest.cs index 49433c43172..61c7f200068 100644 --- a/test/EFCore.Relational.Tests/RelationalEventIdTest.cs +++ b/test/EFCore.Relational.Tests/RelationalEventIdTest.cs @@ -145,11 +145,9 @@ private class FakeRelationalConnection : IRelationalConnection public DbContext Context => null; public Guid ConnectionId => Guid.NewGuid(); public int? CommandTimeout { get; set; } - public Task CloseAsync(CancellationToken cancellationToken = default) => throw new NotImplementedException(); + public Task CloseAsync() => throw new NotImplementedException(); public bool IsMultipleActiveResultSetsEnabled => throw new NotImplementedException(); public IDbContextTransaction CurrentTransaction => throw new NotImplementedException(); - public Transaction EnlistedTransaction { get; } - public void EnlistTransaction(Transaction transaction) => throw new NotImplementedException(); public SemaphoreSlim Semaphore => throw new NotImplementedException(); public IDbContextTransaction BeginTransaction(System.Data.IsolationLevel isolationLevel) => throw new NotImplementedException(); public IDbContextTransaction BeginTransaction() => throw new NotImplementedException(); diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/BadDataSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/BadDataSqliteTest.cs index 890475cc241..1eba7b0a3a1 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/BadDataSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/BadDataSqliteTest.cs @@ -370,8 +370,6 @@ public void RollbackTransaction() } public IDbContextTransaction CurrentTransaction => throw new NotImplementedException(); - public Transaction EnlistedTransaction { get; } - public void EnlistTransaction(Transaction transaction) => throw new NotImplementedException(); public SemaphoreSlim Semaphore { get; } public string ConnectionString { get; } @@ -386,7 +384,7 @@ public Task OpenAsync(CancellationToken cancellationToken, bool errorsExpe public bool Close() => true; - public Task CloseAsync(CancellationToken cancellationToken = default) => Task.FromResult(true); + public Task CloseAsync() => Task.FromResult(true); public bool IsMultipleActiveResultSetsEnabled { get; } public IDbContextTransaction BeginTransaction(System.Data.IsolationLevel isolationLevel) => throw new NotImplementedException(); diff --git a/test/EFCore.Tests/ApiConsistencyTestBase.cs b/test/EFCore.Tests/ApiConsistencyTestBase.cs index 021cd32d249..b9e77533ecd 100644 --- a/test/EFCore.Tests/ApiConsistencyTestBase.cs +++ b/test/EFCore.Tests/ApiConsistencyTestBase.cs @@ -178,6 +178,19 @@ from parameter in method.GetParameters() [ConditionalFact] public virtual void Async_methods_should_have_overload_with_cancellation_token_and_end_with_async_suffix() { + var withoutCancellationToken = new HashSet + { + "RelationalDatabaseFacadeExtensions.CloseConnectionAsync", + "IRelationalConnection.CloseAsync", + "RelationalConnection.CloseAsync", + "DbConnectionInterceptor.ConnectionClosingAsync", + "DbConnectionInterceptor.ConnectionClosedAsync", + "IDbConnectionInterceptor.ConnectionClosingAsync", + "IDbConnectionInterceptor.ConnectionClosedAsync", + "RelationalLoggerExtensions.ConnectionClosingAsync", + "RelationalLoggerExtensions.ConnectionClosedAsync" + }; + var asyncMethods = (from type in GetAllTypes(TargetAssembly.GetTypes()) where type.GetTypeInfo().IsVisible @@ -194,7 +207,8 @@ where method.GetParameters().Any(pi => pi.ParameterType == typeof(CancellationTo var asyncMethodsWithoutToken = (from method in asyncMethods - where method.GetParameters().All(pi => pi.ParameterType != typeof(CancellationToken)) + where !withoutCancellationToken.Contains(method.DeclaringType.Name + "." + method.Name) + && method.GetParameters().All(pi => pi.ParameterType != typeof(CancellationToken)) select method).ToList(); var missingOverloads