3

我正在尝试使用 Oracle 的 Dapper,我试图运行一个多结果集查询,但 Oracle 需要一个 dbtype 的 refcursor。

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 Server 中的 TVP,但应该在这种情况下工作。但是,我也很乐意为任何看起来像 dbparameter 的类型添加特殊大小写 - 并直接添加它们,这样您就可以直接添加 oracleparameter。

  2. DynamicParameters 是关于要添加多少参数,因此它与 value vs DbParameter 讨论有点正交。目前,代码通常更喜欢自己控制添加参数,因此调用者只知道“一个名为 id 且值为 7 的 int”——而不是任何 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 参数知识来妨碍调用代码;到目前为止,我更喜欢:

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

它做同样的事情,但没有下降到 ADO.NET;如果您使用的是“装饰的”ADO.NET 连接(例如 mini-profiler),这一点尤其重要——在这种情况下,您获得的层不是/OracleCommandOracleConnection——它是抽象的。这意味着强制添加 anOracleParameter 可能并不总是有效- 但添加带有名称"foo"和值的参数123- 这是非常可靠的。

于 2013-05-28T16:38:43.987 回答