为什么说是最佳实践呢? 因为在实际开发中踩坑了, 而且发现网上大多数文章给出的解决方法都不能很好地解决问题. 尤其是在获取类型为 OracleDbType.RefCursor, 输出为: ParameterDirection.Output 数据的时候. 网上千篇一律的说写一个 OracleDynamicParameters 的扩展. 但是给出的代码 OracleDynamicParameters 中对于 Get 方法都没有贴出代码或者 Get 方法的书写存在一定的问题. 这就导致了, 如果你执行一个 Oracle 存储过程并且获取 OracleDbType.RefCursor 类型的输出值的时候就会爆 "OracleDbType 无法转换成 CLR 类型" 的问题. 具体的异常提示这里就不截图了, 大致就是需要进行一下 OracleDbType 到 CLR 类型的一个转换.
Dapper 的 DynamicParameters 不支持游标类型
如果你用 Dapper 来进行 Oracle 的存储过程的操作, 刚好这个存储过程需要传入一个游标类型的输出值, 如下所示, 你会发现在 DbType 中是不包含游标类型的.
- var p = new DynamicParameters();
- p.Add("foo", "bar");
- p.Add("baz_cursor", dbType: DbType.?(没有游标类型) , direction: ParameterDirection.Output);
自定义 OracleDynamicParameters 来支持游标类型
不知道大家还有咩有印象, 我在 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 语句.
最后
今天给大家分享了一个我们. NET Core 中使用 Dapper 操作 Oracle 存储过程遇到的坑, 同时给出了个人认为是最佳实现的解决方法. 希望对大家有所帮助. Dapper 是一个好的工具, 可以让你编写高性能的数据库操作代码. 但是, 有时在对 Oracle 的支持上, 可能有一些欠缺, 这时候就有一批乐于分享, 甘于贡献的编程爱好者来分享优秀的扩展来让我们远离 996.
最后的最后也呼吁大家一起来分享, 为. NET Core 社区贡献一份力. 我是依乐祝, 我为自己带盐!!! 有兴趣的小伙伴可以扫码下方二维码关注我的公众号, 不定期分享. NET Core 实战技巧.
来源: https://www.cnblogs.com/yilezhu/p/10791877.html