Skip to content

[API Proposal]: System.Data.IAsyncDbConnection #81723

@SoftStoneDevelop

Description

@SoftStoneDevelop

Background and motivation

System.Data.Common.DbConnection already contains methods such as BeginTransactionAsync, CloseAsync and other asynchronous versions of the System.Data.IDbConnection interface. It would be convenient to inherit DbConnection from System.Data.IAsyncDbConnection.

API Proposal

From IDbConnection we select the common:

    public interface IDbConnectionCommon
    {
        //
        // Summary:
        //     Gets or sets the string used to open a database.
        //
        // Returns:
        //     A string containing connection settings.
        string ConnectionString { get; set; }
        //
        // Summary:
        //     Gets the time to wait (in seconds) while trying to establish a connection before
        //     terminating the attempt and generating an error.
        //
        // Returns:
        //     The time (in seconds) to wait for a connection to open. The default value is
        //     15 seconds.
        int ConnectionTimeout { get; }
        //
        // Summary:
        //     Gets the name of the current database or the database to be used after a connection
        //     is opened.
        //
        // Returns:
        //     The name of the current database or the name of the database to be used once
        //     a connection is open. The default value is an empty string.
        string Database { get; }
        //
        // Summary:
        //     Gets the current state of the connection.
        //
        // Returns:
        //     One of the System.Data.ConnectionState values.
        ConnectionState State { get; }
    }

The IDbConnection interface then inherits from IDbConnectionCommon:

    //
    // Summary:
    //     Represents an open connection to a data source, and is implemented by .NET Framework
    //     data providers that access relational databases.
    public interface IDbConnection : IDbConnectionCommon, IDisposable
    {
        //
        // Summary:
        //     Begins a database transaction.
        //
        // Returns:
        //     An object representing the new transaction.
        IDbTransaction BeginTransaction();
        //
        // Summary:
        //     Begins a database transaction with the specified System.Data.IsolationLevel value.
        //
        // Parameters:
        //   il:
        //     One of the System.Data.IsolationLevel values.
        //
        // Returns:
        //     An object representing the new transaction.
        IDbTransaction BeginTransaction(IsolationLevel il);
        //
        // Summary:
        //     Changes the current database for an open Connection object.
        //
        // Parameters:
        //   databaseName:
        //     The name of the database to use in place of the current database.
        void ChangeDatabase(string databaseName);
        //
        // Summary:
        //     Closes the connection to the database.
        void Close();
        //
        // Summary:
        //     Creates and returns a Command object associated with the connection.
        //
        // Returns:
        //     A Command object associated with the connection.
        IDbCommand CreateCommand();
        //
        // Summary:
        //     Opens a database connection with the settings specified by the ConnectionString
        //     property of the provider-specific Connection object.
        void Open();
    }

The IAsyncDbConnection interface will be like this:

    public interface IAsyncDbConnection : IDbConnectionCommon, IAsyncDisposable
    {
        //
        // Summary:
        //     Asynchronously begins a database transaction.
        //
        // Parameters:
        //   cancellationToken:
        //     An optional token to cancel the asynchronous operation. The default value is
        //     System.Threading.CancellationToken.None.
        //
        // Returns:
        //     A task whose System.Threading.Tasks.Task`1.Result property is an object representing
        //     the new transaction.
        ValueTask<IDbTransaction> BeginTransactionAsync(CancellationToken cancellationToken = default);

        //
        // Summary:
        //     Asynchronously begins a database transaction.
        //
        // Parameters:
        //   isolationLevel:
        //     One of the enumeration values that specifies the isolation level for the transaction
        //     to use.
        //
        //   cancellationToken:
        //     An optional token to cancel the asynchronous operation. The default value is
        //     System.Threading.CancellationToken.None.
        //
        // Returns:
        //     A task whose System.Threading.Tasks.Task`1.Result property is an object representing
        //     the new transaction.
        ValueTask<IDbTransaction> BeginTransactionAsync(IsolationLevel isolationLevel, CancellationToken cancellationToken = default);

        //
        // Summary:
        //     Asynchronously changes the current database for an open connection.
        //
        // Parameters:
        //   databaseName:
        //     The name of the database for the connection to use.
        //
        //   cancellationToken:
        //     An optional token to cancel the asynchronous operation. The default value is
        //     System.Threading.CancellationToken.None.
        //
        // Returns:
        //     A task representing the asynchronous operation.
        Task ChangeDatabaseAsync(string databaseName, CancellationToken cancellationToken = default);

        //
        // Summary:
        //     Asynchronously closes the connection to the database.
        //
        // Returns:
        //     A System.Threading.Tasks.Task representing the asynchronous operation.
        Task CloseAsync();

        //
        // Summary:
        //     An asynchronous version of System.Data.Common.DbConnection.Open, which opens
        //     a database connection with the settings specified by the System.Data.Common.DbConnection.ConnectionString.
        //     This method invokes the virtual method System.Data.Common.DbConnection.OpenAsync(System.Threading.CancellationToken)
        //     with CancellationToken.None.
        //
        // Returns:
        //     A task representing the asynchronous operation.
        Task OpenAsync();

        //
        // Summary:
        //     This is the asynchronous version of System.Data.Common.DbConnection.Open. Providers
        //     should override with an appropriate implementation. The cancellation token can
        //     optionally be honored. The default implementation invokes the synchronous System.Data.Common.DbConnection.Open
        //     call and returns a completed task. The default implementation will return a cancelled
        //     task if passed an already cancelled cancellationToken. Exceptions thrown by Open
        //     will be communicated via the returned Task Exception property. Do not invoke
        //     other methods and properties of the DbConnection object until the returned Task
        //     is complete.
        //
        // Parameters:
        //   cancellationToken:
        //     The cancellation instruction.
        //
        // Returns:
        //     A task representing the asynchronous operation.
        Task OpenAsync(CancellationToken cancellationToken);
    }

Then the DbConnection inheritance will be like this::

public abstract class DbConnection : Component, IDbConnection, IDisposable, IAsyncDbConnection, IAsyncDisposable

API Usage

    public async void SomeMethod(IAsyncDbConnection dbConnection)
    {
        await dbConnection.OpenAsync();
        await using (dbConnection)
        {
            await using (var transaction = await dbConnection.BeginTransactionAsync())
            {
                //do something
            }
        }
    }

Alternative Designs

Do not allocate the common IDbConnectionCommon interface, but duplicate its elements in IAsyncDbConnection. This way the IDbConnection will not be changed.

Risks

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions