33

コンパイルエラー

「System.Data.SqlClient.SqlConnection」には「Query」という名前の適用可能なメソッドはありませんが、その名前の拡張メソッドがあるようです。拡張メソッドを動的にディスパッチすることはできません。動的引数をキャストするか、拡張メソッド構文なしで拡張メソッドを呼び出すことを検討してください。

これで、問題を回避する方法はわかりましたが、エラー自体をよりよく理解しようとしています。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");

それはうまくコンパイルされます。

それで、誰かが私がそれらの他のメソッドの中で同じオーバーロードを利用することがそのエラーで失敗する理由を理解するのを手伝ってくれますか?

4

2 に答える 2

46

それで、誰かが私がそれらの他のメソッドの中で同じオーバーロードを利用することがそのエラーで失敗する理由を理解するのを手伝ってくれますか?

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

ただし、解決策は単純です。静的メソッドを直接呼び出すだけです。

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

(もちろん、あなたが本当にparamタイプである必要があると仮定しています...コメントに記載されているように、それをに変更するだけで大​​丈夫かもしれません。)dynamicobject

于 2013-03-13T16:40:36.637 に答える
1

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

同じコンパイルエラーが発生しました:

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

これは次のようにして解決されました:

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

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

于 2015-12-01T16:03:47.257 に答える