Dapperは型から厳密に型付けされたコレクション

c# dapper

質問

私のアプリケーションではDapperを使ってデータベースにアクセスします。

私は次のコード例を持っています:

public IEnumerable GetByParentId(Type childType, string table) 
{
    IDbConnection _connection = _dbProvider.GetConnection();

    var _sqlString = "select * from " + table;

    IEnumerable _ret = _connection.Query(_sqlString).ToList(); 
    //return IEnumerable<Dapper.SqlMapper.FastExpando> 

    return _ret;
}

FastExpandoアイテムを私のchildTypeにキャストしたり、厳密に型指定されたコレクションを返すようにDapperを強制することは可能ですか?

メソッドシグネチャを変更することはできません!

受け入れられた回答

Reflectionを介してQueryメソッドを呼び出し、childTypeの汎用TItem引数を指定することができます。その後、DapperはIEnumerableを返し、キャストすることができます。また、Dapperをフォークすることもできます(それほど大きくありません)。Queryの非常に単純なオーバーロードを行います。これには、(type childType)引数が含まれ、内部に適切なメソッドが呼び出されます。

あなたが直面するのは、ジェネリックスを扱う際のC#の問題です。静的型付けされた言語であるため、C#は動的型ではうまく機能しません。動的に作業したい場合は、常にリフレクションで終わります。

ここでは、型引数を使用してqueryメソッドを呼び出す方法のサンプルを示します。これを少し修正しなければならないかもしれません:

    public IEnumerable GetByParentId(Type childType, string table)
    {
        IDbConnection _connection = _dbProvider.GetConnection();

        var _sqlString = "select * from " + table;

        var t = typeof(SqlMapper);
        var genericQuery = t.GetMethods().Where(x => x.Name == "Query" && x.GetGenericArguments().Length == 1).First(); // You can cache this object.
        var concreteQuery = genericQuery.MakeGenericMethod(childType); // you can also keep a dictionary of these, for speed.
        var _ret = (IEnumerable)concreteQuery.Invoke(null, new object[] { _connection, _sqlString });

        return _ret;
    }

追加:

また、ここではより一般的な設計上の問題があります。型を動的に指定したいが、静的に型指定されたオブジェクトを取得したい、キャストできる(静的に仮定するか、リフレクションを続けたいか)。それでは...なぜ、最初に動的インターフェイスを作成するのですか?インターフェイスを変更することはできないが、これはちょっとばかげているようだ。すべてのコンテキストは静的に型付けされているようですが、何らかの理由で動的に型指定されたメソッドが1つあります。コンパイル時に型を知っている場合(またはランタイムの汎用引数を介して)、メソッドを次のように変更するだけです。

    public IEnumerable<T> GetByParentId<T>(string table)
    {
        IDbConnection _connection = _dbProvider.GetConnection();
        var _sqlString = "select * from " + table;
        var _ret = _connection.Query<T>(_sqlString);
        return _ret;
    }


ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow