设为首页 加入收藏

TOP

Dapper完美兼容Oracle 执行存储过程并返回结果
2015-11-21 01:39:30 来源: 作者: 【 】 浏览:1
Tags:Dapper 完美 兼容 Oracle 执行 存储 过程 返回 结果
这个问题,困扰了我整整两天。
?
刚刚用到Dapper的时候,感觉非常牛掰。特别是配合.net 4.0新特性dynamic,让我生成泛型集合,再转json一气呵成。
?
不过,各种ORM总有让人吐槽的地方。。。
?
比如,我之前在SqlServer上写测试,搞封装,没有任何问题。CURD、批量操作、存储过程、事物等。
?
可是以转到Oracle上,就出问题了【喂~不是说好的支持Oracle的么】
?
在写Dapper+Oracle单元测试的前期,是没有问题的,也就是说普通的Sql操作是没有任何问题的。
?
然后,我写到存储过程的单元测试的时候,就蛋疼了。
?
因为原版采用的DbType数据类型枚举。Sqlserver返回结果集并没有输出游标。
?
但是Oracle输出结果集,就需要用游标了。那么,这里问题就来了。给OracleParameter设置参数类型,DbType并没有Cursor游标类型。
?
关于Dapper的文档也是不多,而且大部分都集中在SqlServer上,可能应为服务于.Net平台,比较侧重于微软的配套 数据库
?
好吧,问题来了,那就解决。反正是开源的。源代码都有。
?
先根据问题来搜索【我不喜欢用百度,因为百度搜出来一大堆不相关的东西,铜臭味太重。google在国内有无法访问,我就选择了Bing,结果效果还不错。】
?
经过网上搜集,发现Dapper确实是支持 Oracle的,但是对于调用Oracle存储过程的内容却没有。
?
好吧,没有的话,先自己分析分析。
?
既然是参数类型不支持,那么换成支持的不就成了?
?
原版的是这样的:
?
1 DynamicParameters dp = new DynamicParameters();
2 dp.Add("RoleId", "1");
3 dp.Add("RoleName", "", DbType.String, ParameterDirection.Output);
这是Dapper原版中,声明parameter的部分,上面代码红色部分,就是指定参数类型。
?
在system.data.oracleclient 中,有OracleType这个枚举有Cursor类型。
?
然后,去查看 DynamicParameters 类,如下图:
?
?
可以看到,这个类,是实现了一个接口的。说明,原作者给我们预留了接口去自己实现其他内容。
?
继续看看接口:
?
?
接口的内容很简单,就是一个AddParameters方法。
?
那么,可以确定,上面的猜测是对的。
?
我们直接扩展实现这个接口就可以了。如图:
?
?
自己去创建一个实现了IDynamicParameters的类OracleDynamicParameters。
?
然后参照原作者提供的DynamicParameters类来实现这个接口。
?
最终修改版如下(代码多,展开了直接贴到你的文件里面):
?
?View Code
ok,扩展写完了,来一个单元测试,试一试:

 1         /// 
 2         /// 执行带参数存储过程,并返回结果
 3         /// 
 4         public static void ExectPro()
 5         {
 6             var p = new OracleDynamicParameters();
 7             p.Add("beginTime", 201501);
 8             p.Add("endTime", 201512);
 9             p.Add("targetColumn", "tax");
10             p.Add("vCur", OracleDbType.RefCursor, ParameterDirection.Output);
11             using (IDbConnection conn = new OracleConnection(SqlConnOdp))
12             {
13                 conn.Open();
14                 var aa = conn.Query("p_123c", param: p, commandType: CommandType.StoredProcedure).ToList();
15                 aa.ForEach(m => Console.WriteLine(m.C_NAME));
16             }
17             Console.ReadLine();
18         }

?

结果执行通过,并打印了首列的所有值。
?
那么,Dapper的简单扩展就完成了。
?
写在后面
?
补充说明: 我用的Oracle驱动是ODP.NET,.net是4.0
?
这个ODP.NET的Oracle.DataAccess.dll推荐从你的目标服务器,复制回来,不要用本地的,反正我用本地的,就提示外部程序错误。猜测是版本问题或者是位数问题。
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇mybatis oracle BLOB类型字段保存.. 下一篇[实验-视频过程]简单有用的备份-o..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: