2013-03-13 8 views
27

コンパイルエラー

「System.Data.SqlClient.SqlConnectionは」「クエリ」という名前の該当メソッドを持っていないが、その名前で拡張メソッドを持っているように見えます。拡張メソッドを動的にディスパッチすることはできません。動的引数をキャストするか、拡張メソッド構文を使用せずに拡張メソッドを呼び出すことを検討してください。「拡張メソッドを動的にディスパッチできない」原因は何ですか?

私はこの問題を回避する方法を知っていますが、エラー自体をよりよく理解しようとしています。 Dapperを活用するために構築しているクラスがあります。最後に私たちのタイプのデータアクセスをより合理化するためのカスタム機能をいくつか追加します。特に、トレースや物事の建物です。しかし、今では、このような単純なのです:

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); 
    } 
} 

が、私は単純に、このような文を発行した場合に興味深いことに、:

_connection.Query("SELECT * FROM SomeTable"); 

を、それがうまくコンパイルされます。

だから、他の方法の中で同じオーバーロードを利用することが、そのエラーで失敗する理由を理解してもらえますか?

+0

@pst、十分に公正で、それは技術的に投げられません。 –

+2

オブジェクトパラメータではなく動的パラメータが必要なのはなぜですか?あなたはそれに対して操作やメソッド呼び出しをしていません。あなたですか? –

答えて

37

他の方法と同じオーバーロードを利用すると、そのエラーで失敗するのはなぜですか?

これは、動的値(param)を引数の1つとして使用しているためです。これは動的ディスパッチを使用することを意味しますが、拡張メソッドでは動的ディスパッチはサポートされていません。

ソリューションがが簡単です:ちょうど直接静的メソッドを呼び出します。

return SqlMapper.Query(_connection, sql, param, transaction, 
         buffered, commandTimeout, commandType); 

(それはもちろん、あなたが本当にタイプdynamicであることがparamを必要とすると仮定しています...コメントで述べたように、あなたもかもしれませんobjectに変更するだけで問題ありません)。

+1

これは***まさに私が探していたものです***、ありがとうJon!あなたの事例でやったように、私はそれに取り組んでも何の問題もなく、最初の方法で行ったように、私はちょっと知りたいと思っていました***なぜ***なのでしょうか。そして、私はそれを操作する必要はないので、オブジェクトに変更すると思います。 –

+1

@MichaelPerrenoudおそらく既にこれを見つけましたが、この場合の 'Foo'は' SqlMapper'です。だから 'SqlMapper.Query(...) ' –

+0

@MarcGravell:ありがとう、修正されました。 –

1

同じ問題のもう1つの解決策は、動的値に型キャストを適用することです。

は、私は同じコンパイルエラーが発生しました:行うことによって解決された

Url.Asset("path/" + article.logo); 

Url.Asset("path/" + (string) article.logo); 

注:動的な値は、この場合には、文字列であることをよく知られています。存在する文字列連結によって強化された事実。

関連する問題