リフレクションを介して Query メソッドを呼び出し、childType のジェネリック TItem 引数を指定できます。すると、Dapper は IEnumerable を返し、それをキャストできるようになります。また、Dapper をフォークして (それほど大きくはありません)、Query の非常に単純なオーバーロードを作成することもできます。これには (Type childType) 引数が含まれ、内部で適切なメソッドが呼び出されます。
あなたが直面しているのは、ジェネリックを扱う際の C# の問題です。静的に型付けされた言語であるため、C# は動的型の操作には適していません。動的に作業したい場合は、常に反射になります。
型引数を使用してクエリ メソッドを呼び出す方法のサンプルを次に示します。これを少し修正する必要があるかもしれません:
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;
}