web-dev-qa-db-ja.com

Dapper ORMで動的タイプList <dynamic>を返す方法

私はしばらくの間Dapper.netを使用していますが、これは非常に優れたORMマッパーであり、.Net動的型でうまく機能します。

しかし、Dapperがデータベースからデータを取得すると、DapperRow型として返されることに気付きました。

System.Dynamic.ExpandoObjectのような他のタイプで返す方法はありますか?

31
Husni Jabir

DapperRowオブジェクトは、行間で多くの状態を共有するように設計されています。たとえば、40行をフェッチする場合、列名などはonceのみ保存されます。 ExpandoObjectを使用した場合、行ごとに構成する必要があります。したがって、舞台裏の実装の詳細としてDapperRowを使用することは、意図的な効率の問題です。

dynamic AP​​Iから返されるオブジェクトは、IDictionary<string,object>としてキャストすることもできます。

ただし、この辞書の使用をサポートするotherタイプをサポートすることはできます-ExpandoObjectは1です。はい、そうですcould

var rows = conn.Query<ExpandoObject>(...);

動作します。 supportにコードを要求するだけで、そのコードは現在存在しません。だから「いいえ、しかしおそらく将来のビルドで」。

DapperRowを使用する必要がないことにも注意してください...詳細expectedシナリオは、汎用APIを使用して独自の型を具体化します。

28
Marc Gravell

私はこの問題を抱えており、この方法で解決しました!

Query()関数は、実際にDapper.SqlMapper.DapperRowオブジェクトタイプであるダイナミクスのコレクションを返します。 Dapper.SqlMapper.DapperRowはプライベートです。 Dapper.SqlMapper.DapperRowオブジェクトにプロパティを動的に追加する必要がありましたが、機能しないようです。その結果、Dapper.SqlMapper.DapperRowExpandoObjectに変換したかったのです。

以下のようなこの汎用ヘルパーメソッドを作成できました。

public class DapperHelpers
{
     public static dynamic ToExpandoObject(object value)
     {
         IDictionary<string, object> dapperRowProperties = value as IDictionary<string, object>;

         IDictionary<string, object> expando = new ExpandoObject();

         foreach (KeyValuePair<string, object> property in dapperRowProperties)
             expando.Add(property.Key, property.Value);

         return expando as ExpandoObject;
     }
}

次に、これを次のように使用できます。

IEnumerable<ExpandoObject> result = 
           db.SqlConn.Query(sqlScript)
               .Select(x=> (ExpandoObject)ToExpandoObject(x));

参照: dapper-dot-net issues 166

11
Behzad