我正在尝试使用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有什么好处(假设类型已知等)?
答案 0 :(得分:4)
在最新的版本中添加了一个新界面,允许对参数进行更多控制 - 它被添加到SQL服务器中支持TVP,但应该在这种情况下工作。但是,我也非常满足于为任何看起来像dbparameter的类型添加特殊外壳 - 并直接添加它们,这样就可以直接添加oracle参数。
DynamicParameters是关于要添加多少个参数,因此它与值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-parameter知识来阻止调用代码,除非它真的真的需要知道;我到目前为止更喜欢:
var args = new {
foo = 123, bar = "abc"
};
完全完全相同的东西,但没有放弃到ADO.NET;如果您使用“装饰”的ADO.NET连接(例如,迷你探查器),这一点尤其重要 - 在这种情况下,您获得的层是而不是 OracleCommand
/ { {1}}等 - 它是抽象的。这意味着强行添加OracleConnection
可能并不总是有效 - 但添加名称为OracleParameter
且值为"foo"
的参数 - 这非常可靠。