System.Data.SqlClient.SqlCommand has methods
BeginExecuteNonQuery
BeginExecuteReader
BeginExecuteXmlReader
and
EndExecuteNonQuery
EndExecuteReader
EndExecuteXmlReader
for asynchronous execution.
System.Data.IDbCommand only has
ExecuteNonQuery
ExecuteReader
ExecuteXmlReader
which are for synchronous operations only.
Is there any interface for asynchronous operations ?
In addition, why is there no BeginExecuteScalar ?
No there are not interfaces for them
The reason why there is not a
BeginExecuteScalar
is because you probably won't need an async call to get one single value back which should be very quickI recommend to treat
DbCommand
and its friends as if they were interfaces when consuming database APIs. For the sake of generalizing an API over various database providers,DbCommand
achieves just as well asIDbCommand
—or, arguably, better, because it includes newer technologies such as properawait
ableTask
*Async()
members.MS can’t add any new methods with new functionality to
IDbCommand
. If they were to add a method toIDbCommand
, it is a breaking change because anyone is free to implement that interface in their code and MS has put much effort into preserving ABI and API compatibility in the framework. If they expanded interfaces in a release of .net, customer code which previously worked would stop compiling and existing assemblies which are not recompiled would start encountering runtime errors. Additionally, they can’t add proper*Async()
orBegin*()
methods via extension methods without doing ugly casting toDbCommand
behind the scenes (which is a bad practice itself, breaking type safety and unnecessarily introducing dynamic runtime casting).On the other hand, MS can add new virtual methods to
DbCommand
without breaking ABI. Adding new methods to a base class might be considered breaking the API (compile-time, not as bad to break as runtime) because if you inheritedDbCommand
and had added a member with the same name, you’ll start getting the warning CS0108: 'member1' hides inherited member 'member2'. Use the new keyword if hiding was intended.). Thus,DbCommand
can get the new features with minimal impact on consuming code which follows good practices (e.g., most stuff will keep working as long as it doesn’t work against the type system and call methods using something likemyCommand.GetType().GetMethods()[3].Invoke(myCommand, …)
).A possible strategy which MS could have used to support people who like interfaces would have been to introduce new interfaces with names like
IAsyncDbCommand
and haveDbCommand
implement them. They haven’t done this. I don’t know why, but they probably didn’t do this because it would increase complication and the alternative of directly consumingDbCommand
provides most of the benefits to consuming interfaces with few downsides. I.e., it would be work with little return.