リストを変換する方法実行時の型(List >)

c# casting dapper dynamic-language-runtime linq

質問

私は、 IEnumerable<dynamic>戻り値signaturを持つメソッドを使用しています。特定の呼び出しの実行時に、 List<Dapper.SqlMapper.FastExpando>

var x0 = repo.Find(proc, param); 
//x0 runtime type is {List<Dapper.SqlMapper.FastExpando>}

LINQPad.Extensions.Dumpx0のランタイムタイプがLINQPad.Extensions.Dumpことを示しますLINQPad.Extensions.Dump List<IDictionary<String, Object>>しかし、キャスト/ List<IDictionary<String, Object>>変換できないようです。 Linqpadダンプのスクリーンショットを以下に示します。 ここに画像の説明を入力

最終的には、各ディクショナリのすべての値を単一のIEnumerable<DateTime>に結合する必要があります。

IEnumerable<DateTime> GetDates(int productId) 
{
    const string proc = "[dbo].[myproc]";
    dynamic param = new { Id = "asdf" };
    var x0 = repo.Find(proc, param); 
    //...
    //linq conversion from x0 to IEnumerable<DateTime> here.
}

エラーが発生しています

List<IDictionary<String, Object>> x5 = repo.Find(proc, param);

結果:

RuntimeBinderException: Cannot implicitly convert type 'object' to
 'System.Collections.Generic
     .List<System.Collections.Generic.IDictionary<string,object>>'.
An explicit conversion exists (are you missing a cast?)

背景:私はDapperラッパーを使用しており、非正規化された結果を返すデータベーステーブル/ストアドプロシージャを変更することはできません。 1データ要素の100行の代わりに、sprocは100行の1行を返します。私は、100列を表すクラスを作成することを避けたいと思い、 Dapperの自動化機能を利用して、columnName、columnValueのIDictionaryを介して列データを行に転置したいと考えました。

UPDATEこれは動的パラメータの問題であるようです。インラインで指定すると動作します。ローカルに指定してからパラメータとして渡すと失敗します。

IEnumerable<DateTime> GetDates(int productId) 
{
    const string proc = "[dbo].[myproc]";
    dynamic param = new { Id = "asdf" };

    //next line throws RuntimeBinderException: 'object' does not 
    //contain a definition for 'First'.
    //IDictionary<String, object> x0 = repo.Find(proc, param).First();

    //this succeeds:
    IDictionary<String, object> x0 = repo.Find(proc, new { Id = "asdf" }).First();

    IEnumerable<DateTime> qry2
       = x0.Values.AsQueryable()
           .Where(x => x != null)
           .Select(x => (DateTime) x);
    return qry2;
}

FindQueryシグネチャは次のとおりです。

//Repository::Find
public IEnumerable<dynamic> Find(string procName, object param = null)

//Dapper SqlMapper::Query
public static IEnumerable<dynamic> Query(this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)

人気のある回答

LINQ Castメソッドを使用して、シーケンス内の各アイテムをキャストできます。

List<IDictionary<String, Object>> data = repo.Find(proc, param)
    .AsEnumerable()
    .Cast<IDictionary<String, Object>>()
    .ToList();


ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ