3

Oracle で Dapper を試していて、複数結果セットのクエリを実行しようとしていましたが、Oracle には refcursor の dbtype が必要です。

StringBuilder query = new StringBuilder("BEGIN ");
query.Append("OPEN :rs1 FOR SELECT * FROM Table1 where key=:KEY; ");
query.Append("OPEN :rs2 FOR SELECT * FROM Table2 where key=:KEY; ");
query.Append("END;");
  • OracleParameter (おそらく DbParameter として) を Dapper に渡す方法はありますか? しようとしたところ、エラーが発生しました。

  • DynamicParameter を使用することと DbParameter を使用することの利点は何ですか (型が既知であると仮定する場合など)?

4

1 に答える 1

4
  1. パラメータをより詳細に制御できる新しいインターフェイスが最新のビルドに追加されました。これは、SQL サーバーで TVP をサポートするために追加されましたが、このシナリオでは機能するはずです。ただし、dbparameter のように見えるすべてのタイプに特別な大文字と小文字を区別して追加し、それらを直接追加することにもかなり満足しています。これにより、oracleparameter を直接追加できるようになります。

  2. DynamicParameters は、追加するパラメーターの数に関するものであるため、値と DbParameter の議論とは少し直交しています。現時点では、通常、コードはパラメーター自体の追加を制御することを好むため、呼び出し元は「値 7 の int という名前の ID」のみを認識し、ado.net の詳細は認識しません。しかし、それは可能です。


編集:本当にパラメータのリスト(つまりList<DbParameter>など)を操作したい場合は、次のようなものでそれを行うことができます:

public class DbParams : Dapper.SqlMapper.IDynamicParameters,
                        IEnumerable<IDbDataParameter>
{
    private readonly List<IDbDataParameter> parameters =
        new List<IDbDataParameter>();
    public IEnumerator<IDbDataParameter> GetEnumerator() {
        return parameters.GetEnumerator(); }
    IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
    public void Add(IDbDataParameter value)
    {
        parameters.Add(value);
    }
    void Dapper.SqlMapper.IDynamicParameters.AddParameters(IDbCommand command,
        Dapper.SqlMapper.Identity identity)
    {
        foreach (IDbDataParameter parameter in parameters)
            command.Parameters.Add(parameter);
    }
}

次のような使い方で:

public void TestCustomParameters()
{
    var args = new DbParams {
        new SqlParameter("foo", 123),
        new SqlParameter("bar", "abc")
    };
    var result = connection.Query("select Foo=@foo, Bar=@bar", args).Single();
    int foo = result.Foo;
    string bar = result.Bar;
    foo.IsEqualTo(123);
    bar.IsEqualTo("abc");
}

これはテストに合格します。

ただし、本当に必要な場合を除き、呼び出し元のコードに db-parameter の知識を持たせたくないことを強調しておきます。私ははるかに好むだろう:

var args = new {
    foo = 123, bar = "abc"
};

これはまったく同じことを行いますが、ADO.NET にドロップすることはありません。これは、「装飾された」ADO.NET 接続 (ミニプロファイラーなど) を使用している場合に特に重要です。この場合、取得するレイヤーは/などではなく、抽象化されています。これは、強制的に を追加しても常に機能するとは限らないことを意味しますが、名前と値を持つパラメーターを追加することはかなり信頼できます。OracleCommandOracleConnectionOracleParameter "foo"123

于 2013-05-28T16:38:43.987 に答える