@@ -373,19 +373,49 @@ private static Task<DbDataReader> ExecuteReaderWithFlagsFallbackAsync(DbCommand
373373 return task ;
374374 }
375375
376+ /// <summary>
377+ /// Attempts to open a connection asynchronously, with a better error message for unsupported usages.
378+ /// </summary>
379+ private static Task TryOpenAsync ( this IDbConnection cnn , CancellationToken cancel )
380+ {
381+ if ( cnn is DbConnection dbConn )
382+ {
383+ return dbConn . OpenAsync ( cancel ) ;
384+ }
385+ else
386+ {
387+ throw new InvalidOperationException ( "Async operations require use of a DbConnection or an already-open IDbConnection" ) ;
388+ }
389+ }
390+
391+ /// <summary>
392+ /// Attempts setup a <see cref="DbCommand"/> on a <see cref="DbConnection"/>, with a better error message for unsupported usages.
393+ /// </summary>
394+ private static DbCommand TrySetupAsyncCommand ( this CommandDefinition command , IDbConnection cnn , Action < IDbCommand , object > paramReader )
395+ {
396+ if ( command . SetupCommand ( cnn , paramReader ) is DbCommand dbCommand )
397+ {
398+ return dbCommand ;
399+ }
400+ else
401+ {
402+ throw new InvalidOperationException ( "Async operations require use of a DbConnection or an IDbConnection where .CreateCommand() returns a DbCommand" ) ;
403+ }
404+ }
405+
376406 private static async Task < IEnumerable < T > > QueryAsync < T > ( this IDbConnection cnn , Type effectiveType , CommandDefinition command )
377407 {
378408 object param = command . Parameters ;
379409 var identity = new Identity ( command . CommandText , command . CommandType , cnn , effectiveType , param ? . GetType ( ) , null ) ;
380410 var info = GetCacheInfo ( identity , param , command . AddToCache ) ;
381411 bool wasClosed = cnn . State == ConnectionState . Closed ;
382412 var cancel = command . CancellationToken ;
383- using ( var cmd = ( DbCommand ) command . SetupCommand ( cnn , info . ParamReader ) )
413+ using ( var cmd = command . TrySetupAsyncCommand ( cnn , info . ParamReader ) )
384414 {
385415 DbDataReader reader = null ;
386416 try
387417 {
388- if ( wasClosed ) await ( ( DbConnection ) cnn ) . OpenAsync ( cancel ) . ConfigureAwait ( false ) ;
418+ if ( wasClosed ) await cnn . TryOpenAsync ( cancel ) . ConfigureAwait ( false ) ;
389419 reader = await ExecuteReaderWithFlagsFallbackAsync ( cmd , wasClosed , CommandBehavior . SequentialAccess | CommandBehavior . SingleResult , cancel ) . ConfigureAwait ( false ) ;
390420
391421 var tuple = info . Deserializer ;
@@ -444,12 +474,12 @@ private static async Task<T> QueryRowAsync<T>(this IDbConnection cnn, Row row, T
444474 var info = GetCacheInfo ( identity , param , command . AddToCache ) ;
445475 bool wasClosed = cnn . State == ConnectionState . Closed ;
446476 var cancel = command . CancellationToken ;
447- using ( var cmd = ( DbCommand ) command . SetupCommand ( cnn , info . ParamReader ) )
477+ using ( var cmd = command . TrySetupAsyncCommand ( cnn , info . ParamReader ) )
448478 {
449479 DbDataReader reader = null ;
450480 try
451481 {
452- if ( wasClosed ) await ( ( DbConnection ) cnn ) . OpenAsync ( cancel ) . ConfigureAwait ( false ) ;
482+ if ( wasClosed ) await cnn . TryOpenAsync ( cancel ) . ConfigureAwait ( false ) ;
453483 reader = await ExecuteReaderWithFlagsFallbackAsync ( cmd , wasClosed , ( row & Row . Single ) != 0
454484 ? CommandBehavior . SequentialAccess | CommandBehavior . SingleResult // need to allow multiple rows, to check fail condition
455485 : CommandBehavior . SequentialAccess | CommandBehavior . SingleResult | CommandBehavior . SingleRow , cancel ) . ConfigureAwait ( false ) ;
@@ -546,7 +576,7 @@ private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandD
546576 bool wasClosed = cnn . State == ConnectionState . Closed ;
547577 try
548578 {
549- if ( wasClosed ) await ( ( DbConnection ) cnn ) . OpenAsync ( command . CancellationToken ) . ConfigureAwait ( false ) ;
579+ if ( wasClosed ) await cnn . TryOpenAsync ( command . CancellationToken ) . ConfigureAwait ( false ) ;
550580
551581 CacheInfo info = null ;
552582 string masterSql = null ;
@@ -562,7 +592,7 @@ private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandD
562592 if ( isFirst )
563593 {
564594 isFirst = false ;
565- cmd = ( DbCommand ) command . SetupCommand ( cnn , null ) ;
595+ cmd = command . TrySetupAsyncCommand ( cnn , null ) ;
566596 masterSql = cmd . CommandText ;
567597 var identity = new Identity ( command . CommandText , cmd . CommandType , cnn , null , obj . GetType ( ) , null ) ;
568598 info = GetCacheInfo ( identity , obj , command . AddToCache ) ;
@@ -577,7 +607,7 @@ private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandD
577607 }
578608 else
579609 {
580- cmd = ( DbCommand ) command . SetupCommand ( cnn , null ) ;
610+ cmd = command . TrySetupAsyncCommand ( cnn , null ) ;
581611 }
582612 info . ParamReader ( cmd , obj ) ;
583613
@@ -604,7 +634,7 @@ private static async Task<int> ExecuteMultiImplAsync(IDbConnection cnn, CommandD
604634 }
605635 else
606636 {
607- using ( var cmd = ( DbCommand ) command . SetupCommand ( cnn , null ) )
637+ using ( var cmd = command . TrySetupAsyncCommand ( cnn , null ) )
608638 {
609639 foreach ( var obj in multiExec )
610640 {
@@ -640,11 +670,11 @@ private static async Task<int> ExecuteImplAsync(IDbConnection cnn, CommandDefini
640670 var identity = new Identity ( command . CommandText , command . CommandType , cnn , null , param ? . GetType ( ) , null ) ;
641671 var info = GetCacheInfo ( identity , param , command . AddToCache ) ;
642672 bool wasClosed = cnn . State == ConnectionState . Closed ;
643- using ( var cmd = ( DbCommand ) command . SetupCommand ( cnn , info . ParamReader ) )
673+ using ( var cmd = command . TrySetupAsyncCommand ( cnn , info . ParamReader ) )
644674 {
645675 try
646676 {
647- if ( wasClosed ) await ( ( DbConnection ) cnn ) . OpenAsync ( command . CancellationToken ) . ConfigureAwait ( false ) ;
677+ if ( wasClosed ) await cnn . TryOpenAsync ( command . CancellationToken ) . ConfigureAwait ( false ) ;
648678 var result = await cmd . ExecuteNonQueryAsync ( command . CancellationToken ) . ConfigureAwait ( false ) ;
649679 command . OnCompleted ( ) ;
650680 return result ;
@@ -910,8 +940,8 @@ private static async Task<IEnumerable<TReturn>> MultiMapAsync<TFirst, TSecond, T
910940 bool wasClosed = cnn . State == ConnectionState . Closed ;
911941 try
912942 {
913- if ( wasClosed ) await ( ( DbConnection ) cnn ) . OpenAsync ( command . CancellationToken ) . ConfigureAwait ( false ) ;
914- using ( var cmd = ( DbCommand ) command . SetupCommand ( cnn , info . ParamReader ) )
943+ if ( wasClosed ) await cnn . TryOpenAsync ( command . CancellationToken ) . ConfigureAwait ( false ) ;
944+ using ( var cmd = command . TrySetupAsyncCommand ( cnn , info . ParamReader ) )
915945 using ( var reader = await ExecuteReaderWithFlagsFallbackAsync ( cmd , wasClosed , CommandBehavior . SequentialAccess | CommandBehavior . SingleResult , command . CancellationToken ) . ConfigureAwait ( false ) )
916946 {
917947 if ( ! command . Buffered ) wasClosed = false ; // handing back open reader; rely on command-behavior
@@ -960,8 +990,8 @@ private static async Task<IEnumerable<TReturn>> MultiMapAsync<TReturn>(this IDbC
960990 bool wasClosed = cnn . State == ConnectionState . Closed ;
961991 try
962992 {
963- if ( wasClosed ) await ( ( DbConnection ) cnn ) . OpenAsync ( ) . ConfigureAwait ( false ) ;
964- using ( var cmd = ( DbCommand ) command . SetupCommand ( cnn , info . ParamReader ) )
993+ if ( wasClosed ) await cnn . TryOpenAsync ( command . CancellationToken ) . ConfigureAwait ( false ) ;
994+ using ( var cmd = command . TrySetupAsyncCommand ( cnn , info . ParamReader ) )
965995 using ( var reader = await ExecuteReaderWithFlagsFallbackAsync ( cmd , wasClosed , CommandBehavior . SequentialAccess | CommandBehavior . SingleResult , command . CancellationToken ) . ConfigureAwait ( false ) )
966996 {
967997 var results = MultiMapImpl ( null , default ( CommandDefinition ) , types , map , splitOn , reader , identity , true ) ;
@@ -1015,8 +1045,8 @@ public static async Task<GridReader> QueryMultipleAsync(this IDbConnection cnn,
10151045 bool wasClosed = cnn . State == ConnectionState . Closed ;
10161046 try
10171047 {
1018- if ( wasClosed ) await ( ( DbConnection ) cnn ) . OpenAsync ( command . CancellationToken ) . ConfigureAwait ( false ) ;
1019- cmd = ( DbCommand ) command . SetupCommand ( cnn , info . ParamReader ) ;
1048+ if ( wasClosed ) await cnn . TryOpenAsync ( command . CancellationToken ) . ConfigureAwait ( false ) ;
1049+ cmd = command . TrySetupAsyncCommand ( cnn , info . ParamReader ) ;
10201050 reader = await ExecuteReaderWithFlagsFallbackAsync ( cmd , wasClosed , CommandBehavior . SequentialAccess , command . CancellationToken ) . ConfigureAwait ( false ) ;
10211051
10221052 var result = new GridReader ( cmd , reader , identity , command . Parameters as DynamicParameters , command . AddToCache , command . CancellationToken ) ;
@@ -1108,8 +1138,8 @@ private static async Task<IDataReader> ExecuteReaderImplAsync(IDbConnection cnn,
11081138 bool wasClosed = cnn . State == ConnectionState . Closed ;
11091139 try
11101140 {
1111- cmd = ( DbCommand ) command . SetupCommand ( cnn , paramReader ) ;
1112- if ( wasClosed ) await ( ( DbConnection ) cnn ) . OpenAsync ( command . CancellationToken ) . ConfigureAwait ( false ) ;
1141+ cmd = command . TrySetupAsyncCommand ( cnn , paramReader ) ;
1142+ if ( wasClosed ) await cnn . TryOpenAsync ( command . CancellationToken ) . ConfigureAwait ( false ) ;
11131143 var reader = await ExecuteReaderWithFlagsFallbackAsync ( cmd , wasClosed , commandBehavior , command . CancellationToken ) . ConfigureAwait ( false ) ;
11141144 wasClosed = false ;
11151145 return reader ;
@@ -1182,8 +1212,8 @@ private static async Task<T> ExecuteScalarImplAsync<T>(IDbConnection cnn, Comman
11821212 object result ;
11831213 try
11841214 {
1185- cmd = ( DbCommand ) command . SetupCommand ( cnn , paramReader ) ;
1186- if ( wasClosed ) await ( ( DbConnection ) cnn ) . OpenAsync ( command . CancellationToken ) . ConfigureAwait ( false ) ;
1215+ cmd = command . TrySetupAsyncCommand ( cnn , paramReader ) ;
1216+ if ( wasClosed ) await cnn . TryOpenAsync ( command . CancellationToken ) . ConfigureAwait ( false ) ;
11871217 result = await cmd . ExecuteScalarAsync ( command . CancellationToken ) . ConfigureAwait ( false ) ;
11881218 command . OnCompleted ( ) ;
11891219 }
0 commit comments