値の配列が与えられたので、これらの値に基づくプロパティを持つ匿名オブジェクトを作成したいと思います。プロパティ名は、配列内の値のインデックスである"pN"
だけです。N
たとえば、与えられた
object[] values = { 123, "foo" };
匿名オブジェクトを作成したい
new { p0 = 123, p1 = "foo" };
これを行うために私が考えることができる唯一の方法は、サポートするために妥当な数のパラメーターまでswitch
または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ステートメントを実行する既存のメソッドのセットがあります。メソッドは通常string
、sqlステートメント用にaを取りparams object[]
、パラメーターがある場合はaを取ります。クエリでパラメータを使用する場合、それらの名前はになります@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を使用して、 Dapperのメソッドをラップおよび公開Query<T>
し、既存のメソッドと一貫性のある方法でこれを行います。たとえば、次のようになります。
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にパラメータを渡すための匿名オブジェクトの作成についての私の質問につながります。
DynamicParameter
@Paolo Tedescoの要求に応じて、クラスを使用してコードを追加します。
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
プロパティをチェックすると、コマンドに構成されたパラメーターが表示されません。