動的に決定されたプロパティ名を持つ匿名オブジェクトの作成方法

anonymous-types c# dapper

質問

値の配列が与えられた場合、これらの値に基づいたプロパティを持つ匿名オブジェクトを作成したいと考えています。プロパティ名は単純に"pN"で、 Nは配列内の値のインデックスです。

例えば、与えられた

object[] values = { 123, "foo" };

私は匿名のオブジェクトを作成したいと思います

new { p0 = 123, p1 = "foo" };

私がこれを行うために考えることができる唯一の方法は、 switchを使うかif連鎖if妥当な数のパラメータをサポートすることですが、これを行うもっとエレガントな方法があるかどうか疑問に思っていました:

object[] parameterValues = new object[] { 123, "foo" };
dynamic values = null;

switch (parameterValues.Length)
{
    case 1:
        values = new { p0 = parameterValues[0] };
        break;
    case 2:
        values = new { p0 = parameterValues[0], p1 = parameterValues[1] };      
        break;
    // etc. up to a reasonable # of parameters
}

バックグラウンド

私は、データベースに対してSQL文を実行するメソッドの既存のセットを持っています。これらのメソッドは、通常、SQL文のstringとパラメータのparams object[] (存在する場合)を取ります。クエリがパラメータを使用する場合、名前は@p0, @p1, @p2, etc.ます。

例:

public int ExecuteNonQuery(string commandText, CommandType commandType, params object[] parameterValues) { .... }

これは次のように呼び出されます:

db.ExecuteNonQuery("insert into MyTable(Col1, Col2) values (@p0, @p1)", CommandType.Text, 123, "foo");

DapperのQuery<T>メソッドをラップして公開し、既存のメソッドと一貫性のあるやり方で、このクラス内でDapperを使いたいと思います。

public IEnumerable<T> ExecuteQuery<T>(string commandText, CommandType commandType, params object[] parameterValues) { .... }

DapperのQuery<T>メソッドでは、匿名オブジェクトのパラメータ値が使用されます。

var dog = connection.Query<Dog>("select Age = @Age, Id = @Id", new { Age = (int?)null, Id = guid }); 

Dapperにパラメータを渡すための匿名オブジェクトの作成についての質問につながりました。


@Paolo Tedescoが要求したDynamicParameterクラスを使用したコードの追加

string sql = "select * from Account where Id = @p0 and username = @p1";
dynamic values = new DynamicParameter(123, "test");
var accounts = SqlMapper.Query<Account>(connection, sql, values);

DapperのSqlMapper.csファイルの581行目に例外がスローされます。

using (var reader = cmd.ExecuteReader())

例外はSqlExceptionです。

スカラー変数 "@ p0"を宣言しなければなりません。

cmd.Parametersプロパティをチェックすると、コマンドに設定されたパラメータが表示されません。

人気のある回答

あなたはDapperを悪用しているので、これを行う必要はありません。代わりにIDynamicParameters実装するか、非常に柔軟なDynamicParametersクラスを使用してDynamicParameters

特に:

string sql = "select * from Account where Id = @id and username = @name";
var values = new DynamicParameters();
values.Add("id", 1);
values.Add("name", "bob");
var accounts = SqlMapper.Query<Account>(connection, sql, values);

DynamicParametersは、コンストラクタで匿名クラスをDynamicParametersことができます。あなたはCONCATできるDynamicParameters使用してAddDynamicParams方法を。

さらに、anon-typesには厳密な依存関係はありません。 Dapperは具体的な型をparamsとして許します:

class Stuff
{
   public int Thing { get; set; }
}

...

cnn.Execute("select @Thing", new Stuff{Thing = 1});

Kevinは同様の疑問を抱いていました: POCO上のすべてのプロパティを統合するための、迅速かつ簡単な方法の探し方 - DynamicParametersはマジックフープジャンプを必要とせずにここでも完璧に動作します。



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