フィールドの可変/動的セットを使用してC#で匿名型を宣言することは可能ですか?

anonymous-types c# dapper dynamic

質問

C#では、ランタイムまでフィールドがわからない匿名型を宣言できるかどうかを調べたいと思います。

たとえば、キー/値ペアのリストがある場合、そのリストの内容に基づいて匿名タイプを宣言できますか?私が取り組んでいる具体的なケースは、Dapperにパラメータを渡すことです。ここでは、どれだけ多くのパラメータを事前に知っているのでしょうか。

List<Tuple<string, string>> paramList = new List<Tuple<string, string>>() {
    new Tuple<string, string>("key1", "value1"),
    new Tuple<string, string>("key2", "value2")
    ...
};

私はこのリスト(または同等のマップ)をクエリパラメータとしてDapperに渡すことができる匿名型に変換したいと思います。理想的には、匿名型として定義されている場合、上記のリストは次のようになります:

new { key1=value1, key2=value2, ... }

私は、StackOverflowで、宣言された(「extendoオブジェクト」)、またはオブジェクトの作成後に任意のフィールドを宣言した後に匿名型を拡張することを求めるいくつかの質問を見ましたが、その必要はありません。一度動的に型を宣言すること。私の疑惑は、それが可能であれば、いくらか幻想的な反省を必要とするということです。

コンパイラはコンパイル時にフードの下で匿名クラスの型を定義するので、実行時までそのクラスのフィールドが利用できない場合、私は不運になる可能性があります。私のユースケースは実際にはいつでも、任意のフィールドを定義するためにいつでも "extendoオブジェクト"を使用するよりも実際には違いはありません。

代わりに、(匿名クラスを宣言するのではなく)クエリパラメータをDapperに渡すためのより良い方法が分かっていれば、それについても聞いてみたいと思います。

ありがとう!

更新

これに遅れてごめんね申し訳ありません!これらの答えはすべて素晴らしいものでした。私は誰にもポイントを与えることができればと思います。私はjbtuleのソリューション(サム・サフロン編集)を使ってIDynamicParametersをDapperに渡したので、私は彼に答えを与えなければならないと感じました。他の回答も良かったし、私が聞いた特定の質問に答えました。私は本当に誰もがこれに感謝しています!

受け入れられた回答

Dapperの作成者はこの問題を非常に認識していました。この種の機能は、 INSERTおよびUPDATEヘルパーにとって本当に必要です。

QueryExecute 、およびQueryMultipleメソッドは、 dynamicパラメータを取ります。これは、匿名型、具象型、またはIDynamicParametersを実装するオブジェクトのいずれかです。

public interface IDynamicParameters
{
    void AddParameters(IDbCommand command, Identity identity);
}

このインターフェイスは非常に便利で、 AddParametersはSQLを実行する直前に呼び出されます。これにより、SQLに送信されるパラメータを豊富に制御できるだけでなく、コマンドにアクセスできるので(DB固有のものにキャストできます)、DB固有のDbParametersをフックできます。これにより、テーブル値パラメータなどのサポートが可能になります。

Dapperには、 DynamicParametersという目的に使用できるこのインターフェイスの実装が含まれています。これにより、連結された匿名のパラメータバッグと特定の値の両方を追加することができます。

AddDynamicParamsメソッドを使用して、匿名型を追加できます。

var p = new DynamicParameters();
p.AddDynamicParams(new{a = "1"});
p.AddDynamicParams(new{b = "2", c = "3"});
p.Add("d", "4")
var r = cnn.Query("select @a a, @b b, @c c, @d d", p);
// r.a == 1, r.b == 2, r.c == 3, r.d == 4

人気のある回答

C#では、ランタイムまでフィールドがわからない匿名型を宣言できるかどうかを調べたいと思います。

匿名型は、コンパイラによって生成されます。コンパイラが、コンパイラが知らないフィールド型のコンパイラ生成型生成するかどうかを知りたい場合。明らかにそうすることはできません。あなたが正しく推測すると、あなたは運がありません。

私はStackOverflowのいくつかの質問が、匿名型が宣言された後で拡張することを尋ねてきました( "extendoオブジェクト")

私たちは通常、それらの "expando"オブジェクトを呼び出します。

あなたがしたいことが、キーと値のペアの辞書に基づいてexpandoオブジェクトを作成する場合は、ExpandoObjectクラスを使用してそれを行います。詳細については、このMSDNの記事を参照してください。

http://msdn.microsoft.com/en-us/magazine/ff796227.aspx

あなたがしたいことが実行時に真正な.NETクラスを生成するならば、それを行うこともできます。あなたが正しく注記しているように、あなたはそうするために幻想的なリフレクションを必要とします。あなたがしたいのは、通常のアセンブリとは異なり、実行時に生成するコレクティブアセンブリを作成することです(ガベージコレクタは、完了したらガベージコレクタをクリーンアップします)。

Collectibleアセンブリを作成し、TypeBuilderを使用して型を生成する方法の詳細については、 http://msdn.microsoft.com/en-us/library/dd554932.aspxを参照してください



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