-
Notifications
You must be signed in to change notification settings - Fork 2
Description
From DbConnectionExtensions.cs:
public static async Task<IEnumerable<T>> ReadAsync<T>(
this IDbConnection dbConnection,
CancellationToken cancellationToken,
string query,
object arguments = null, Action<IDbCommand> configureCommand = default)
{
using (var dataReader = await dbConnection.ExecuteReaderAsync(cancellationToken, query, arguments, configureCommand).ConfigureAwait(false))
{
SqlStatement.Current = query;
return dataReader.Read<T>();
}
}
Here you can see that the only async functionality of ReadAsync is ExecuteReaderAsync.
The actual reading of the result is done synchronously and will block for every read.
I'm guessing this is done because IDataReader does not have any async methods available. The ReadAsync-methods are available when using DbDataReader but not through the IDataReader interface. This is most likely to avoid forcing any existing implementers of IDataReader to implement the async methods.
Hopefully, DbReader can check if dataReader is an instance of DbDataReader and then use the proper async Read methods and otherwise use the current sync-methods as a fallback when reader is not an instance of DbDataReader.
There is also an opportunity here to implement an async read method using IAsyncEnumerable instead of allocating a List and returning it as an IEnumerable - where most clients probably immediately calls .ToList() on it. This will also make queries that might return multiple values and the client uses .FirstOrDefault() more efficient since IAsyncEnumerable will only actually fetch and map the data that is iterated.