public static Task<IEnumerable<TResult>> ExecuteQueryAsync<TResult>() is a wrapper for ExecuteQueryAsyncInternal(). This one encapsulates private static DbCommand CreateDbCommandForExecution() which uses synchronous EnsureOpen() call. This renders the entire outer method synchronous if user does not opt in to EnsureOpenAsync() themself. Maybe new async method private static DbCommand CreateDbCommandForExecutionAsync() is needed?
Examples:
// this method will return asap no matter if the connection is closed or open
public async Task<int> GetSomethingAsync()
{
using var connection = await new SqlConnection(connectionString).EnsureOpenAsync().ConfigureAwait(false);
var result = await connection
.ExecuteQueryAsync<int>(@"SELECT 1;")
.ConfigureAwait(false);
return result.FirstOrDefault();
}
// if the connection is closed ExecuteQueryAsync is trying to open it, but synchronously:
public async Task<int> GetSomethingAsync()
{
using var connection = new SqlConnection(connectionString);
var result = await connection
.ExecuteQueryAsync<int>(@"SELECT 1;")
.ConfigureAwait(false);
return result.FirstOrDefault();
}
Great findings! Yes, an overloaded method is needed for this. I will definitely handle this!
As you mentioned, the fix is simple, we can create separate methods and named them CreateDbCommandForExecution and CreateDbCommandForExecutionAsync respectively. Make the current method as internal named CreateDbCommandForExecutionInternal. Then, transfer only the calls to the EnsureOpen and EnsureOpenAync methods to the separated methods, and call this Internal method internally from the 2 separated methods, making sure we do not have repetitive code written.
This is now available at RepoDb v1.12.0.
This has been fixed and is now available at RepoDb v1.12.3. Closing this incident ticket now.