如果你用Dapper来进行Oracle的存储过程的操作,刚好这个存储过程需要传入一个游标类型的输出值,如下所示,你会发现在DbType
中是不包含游标类型的。
var p = new DynamicParameters();
p.Add("foo", "bar");
p.Add("baz_cursor", dbType: DbType.?(没有游标类型) , direction: ParameterDirection.Output);
不知道大家还有咩有印象,我在2018年的时候曾经翻译了一篇关于在.NET Core中使用Dapper操作Oracle的文章,没有印象的可以点击链接查看下[译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了。
这篇文章是翻译的,里面有一个OracleDynamicParameters
的扩展方法的代码,具体的代码大家可以点击上面的链接进行查看,使用这个OracleDynamicParameters
进行Oracle存储过程的查询是不会有问题的,而且也支持包含OracleDbType.RefCursor
类型的存储过程的执行。因为它在Add
参数的时候传入的是数据类型是OracleDbType
类型,如下所示:
因此这里我们可以在添加参数的时候,传入游标类型了。如下所示:
但是这时候,如果这个游标类型是输出参数,这时候你如果通过下面这种方式来直接获取的话,就会爆我们文章开头的错误了。
异常的大概意思就是“返回的是OracleDbType类型,没法直接转换成CLR类型,如上面的int类型”。
既然知道了异常的问题,那么接下来我们就需要解决这个问题了。大概的解决思路也就是重新实现下Get<T>
方案,在获取数据的时候执行下OracleDataType到CLR类型的转换。可能这个对大伙有点难度,但是别担心,我们有GayHub,因此我在GayHub上果然找到了现成的实现,具体的代码可以点这里查看 这里实现的OracleDynamicParameters
比我们实现的更强大,功能也更丰富。同时也实现了Get<T>
方法的转换。如下图所示:
同时,作者也发布了Nuget包,来让你远离996.使用方式如下:
然后在文件中引入Dapper.Oracle
的明明空间就可以了。
同时此项目的GitHub地址有必要贴一下:https://github.com/DIPSAS/Dapper.Oracle
正如作者所说:此程序集添加了对编写Oracle特定SQL的支持,该SQL支持Oracle托管提供程序对参数使用的所有DbType,支持对命令设置各种属性(lobfetchsize、arraybindcount、bindbyname),以及对参数设置collectiontype。使用此包,现在可以运行返回refcursor的存储过程,或者使用数组绑定计数来执行带有参数数组的SQL语句。