'System.Data.SqlClient.SqlConnection' has no applicable method named 'Query' but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax.
Now, I know how to work around the problem, but I'm trying to get a better understanding of the error itself. I have class that I'm building to leverage Dapper. In the end I'm going to provide some more custom functionality to make our type of data access a lot more streamlined. In particular building in tracing and stuff. However, right now it's as simple as this:
public class Connection : IDisposable { private SqlConnection _connection; public Connection() { var connectionString = Convert.ToString(ConfigurationManager.ConnectionStrings["ConnectionString"]); _connection = new SqlConnection(connectionString); _connection.Open(); } public void Dispose() { _connection.Close(); _connection.Dispose(); } public IEnumerable<dynamic> Query(string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) { // this one works fine, without compile error, so I understand how to // workaround the error return Dapper.SqlMapper.Query(_connection, sql, param, transaction, buffered, commandTimeout, commandType); } public IEnumerable<T> Query<T>(string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) { // this one is failing with the error return (IEnumerable<T>)_connection.Query(sql, param, transaction, buffered, commandTimeout, commandType); } }
but interestingly enough, if I were to simply issue a statement like this:
_connection.Query("SELECT * FROM SomeTable");
it compiles just fine.
So, can somebody please help me understand why leveraging the same overload inside of those other methods is failing with that error?
Extension methods are static because they get the instance passed in via the first parameter, and they don't act on the actual instance of their declaring class. Also, they're just a syntactic sugar. CLR doesn't support such a thing.
An extension method must be a static method. An extension method must be inside a static class -- the class can have any name. The parameter in an extension method should always have the "this" keyword preceding the type on which the method needs to be called.
We can not call the Extension method on the dynamic type.
The only difference between a regular static method and an extension method is that the first parameter of the extension method specifies the type that it is going to operator on, preceded by the this keyword.
So, can somebody please help me understand why leveraging the same overload inside of those other methods is failing with that error?
Precisely because you're using a dynamic value (param
) as one of the arguments. That means it will use dynamic dispatch... but dynamic dispatch isn't supported for extension methods.
The solution is simple though: just call the static method directly:
return SqlMapper.Query(_connection, sql, param, transaction, buffered, commandTimeout, commandType);
(That's assuming you really need param
to be of type dynamic
, of course... as noted in comments, you may well be fine to just change it to object
.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With