我正在使用Dapper和ODP.Net来调用存储过程。 我觉得愚蠢的是没有发现我的参数有什么问题,但在这里它是:
以下是存储过程签名:
PROCEDURE SP_NETWORK_GETALL(UserLogon IN VARCHAR2, NetworkVersionList OUT refCursor)
这是我的.Net电话:
using (var conn = new OracleConnection(connString))
{
var parameters = new List<OracleParameter>
{
new OracleParameter()
{
Direction = ParameterDirection.Input,
ParameterName = "UserLogon",
OracleDbType = OracleDbType.Varchar2,
Size = 4000,
Value = "TEST"
},
new OracleParameter()
{
Direction = ParameterDirection.Output,
OracleDbType = OracleDbType.RefCursor,
ParameterName = "NetworkVersionList",
Value = DBNull.Value
},
};
var results = conn.Query("SDTM.PKG_SP_GET.SP_NETWORK_GETALL", parameters, commandType: CommandType.StoredProcedure);
}
我已经尝试过这个存储过程,它有效。我已经将Dapper用于其他存储过程,它也可以。我试过更改参数的顺序(首先是引用光标),是否设置了VarChar2参数的大小,是否为引用光标设置了DBNull.Value。
我在stackoverflow或互联网上看到了一百万个像这样的问题,但我看不到这里的参数不匹配......
答案 0 :(得分:1)
问题在于您将OracleParameter对象列表发送给dapper&#34;&#34;参数&#34;变量。 Dapper意味着与提供商无关,并且您正在发送提供商特定类型。
看一下dapper代码中的GetCacheInfo方法,你会看到dapper试图处理参数的三种情况:
你可能会陷入默认情况,但是因为你有一个proc,命令中没有令牌,也没有添加任何参数。即使它们是,它可能会通过List&lt;&gt;类型的属性进行搜索。并且它不会找到匹配。
添加IDynamicParameters可让您控制参数及其工作原理。这与odp.net无关。
我认为这是我和所有ORM一样精力充沛的烦恼 - 尽管他们会努力尝试,但总是会成为提供者特定的东西,而这些东西不能被抽象出来。这就是为什么我更喜欢简单地设置特定于提供者的命令,然后使用仅执行映射的实用程序类(不关心连接/设置/执行)。