OleDbを使用してDapperでクエリパラメータを渡す

dapper oledb

質問

このクエリは、 No value given for one or more required parametersというエラーを生成しNo value given for one or more required parameters

using (var conn = new OleDbConnection("Provider=..."))
{
  conn.Open();
  var result = conn.Query(
    "select code, name from mytable where id = ? order by name",
    new { id = 1 });
}

クエリ文字列を: ... where id = @id ...に変更すると、エラーが発生します。 Must declare the scalar variable "@id".がありますMust declare the scalar variable "@id".

クエリ文字列を作成するにはどうすればいいですか?パラメータを渡すにはどうすればよいですか?

受け入れられた回答

現在のソースコード(まだNuGetにはリリースされていません)がこの問題に対処しています。次の作業が必要です。

var result = conn.Query(
"select code, name from mytable where id = ?id? order by name",
new { id = 1 });

エキスパート回答

重要: 新しい回答を見る


現在のビルドでは、次の2つの理由から、その答えは「いいえ」になります。

  • コードは未使用のパラメータをフィルタリングしようとしていますが、SQLでは@id:idまたは?idようなものを見つけることができないため、現在はすべてを削除しています
  • 型から値を追加するためのコードは、(リフレクションはメンバの順番を保証しないため)任意の(well、ok:アルファベット順)順序を使用し、位置無名引数を不安定にします

良いニュースは、これらの両方が修正可能であることです

  • フィルタリングの動作を条件付きにすることができます
  • すべてのプロパティ名に一致するコンストラクタを持つ型のカテゴリを検出し、コンストラクタ引数の位置を使用してプロパティの合成順序を決定することができます。匿名型はこのカテゴリに分類されます

私のローカルクローンに変更を加えると、次のようになります:

// see https://stackoverflow.com/q/18847510/23354
public void TestOleDbParameters()
{
    using (var conn = new System.Data.OleDb.OleDbConnection(
        Program.OleDbConnectionString))
    {
        var row = conn.Query("select Id = ?, Age = ?", new DynamicParameters(
            new { foo = 12, bar = 23 } // these names DO NOT MATTER!!!
        ) { RemoveUnused = false } ).Single();
        int age = row.Age;
        int id = row.Id;
        age.IsEqualTo(23);
        id.IsEqualTo(12);
    }
}

私は現在DynamicParametersを使用してDynamicParametersますが、これはかなりの数のメソッドに追加する必要があるため、 Query / Query<T>さらに多くのオーバーロードを追加しないようにしています。これをDynamicParameters追加すると、1つの場所で解決されます。

私はこれをプッシュする前にフィードバックに公開しています - それはあなたに見えるでしょうか?


編集:ファンキーなsmellsLikeOleDb (いいえ、冗談ではない)を追加して、これをさらに直接行うことができます:

// see https://stackoverflow.com/q/18847510/23354
public void TestOleDbParameters()
{
    using (var conn = new System.Data.OleDb.OleDbConnection(
        Program.OleDbConnectionString))
    {
        var row = conn.Query("select Id = ?, Age = ?",
            new { foo = 12, bar = 23 } // these names DO NOT MATTER!!!
        ).Single();
        int age = row.Age;
        int id = row.Id;
        age.IsEqualTo(23);
        id.IsEqualTo(12);
    }
}


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