dapper支持oracle游标
dapper支持oracle游标
Dapper是一个轻型的ORM类。它有啥优点、缺点相信很多朋友都知道了,园里也有很多朋友都有相关介绍,这里就不多废话。
如果玩过Oracle都知道,存储过程基本都是通过游标返回数据的,但是dapper原生操作游标会报异常,具体异常信息因为现在没有环境就不截图了。

public FactoryPriceComparisonPublishItem GetTodayFactoryBasePricePushInfo(string weiXinId)
{
using (var cnn = Database.Connection("ERPDataBase"))
{
var p = new OracleDynamicParameters();
p.Add("V_WEIXINID", weiXinId);
p.Add("RetCursor", dbType: OracleDbType.RefCursor, direction: ParameterDirection.Output);
return cnn.Query<FactoryPriceComparisonPublishItem>("PKG_M_STEELMILL.GetFactoryPCPublishItem", param: p, commandType: CommandType.StoredProcedure).SingleOrDefault();
}
}

以上是实际项目的代码片段,通过游标获取查询数据。
那如何去解决这个游标问题呢?就是这个OracleDynamicParameters类,全部内容如下:

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq; using Dapper;
using Oracle.DataAccess.Client; public class OracleDynamicParameters : SqlMapper.IDynamicParameters
{
private static Dictionary<SqlMapper.Identity, Action<IDbCommand, object>> paramReaderCache = new Dictionary<SqlMapper.Identity, Action<IDbCommand, object>>(); private Dictionary<string, ParamInfo> parameters = new Dictionary<string, ParamInfo>();
private List<object> templates; private class ParamInfo
{ public string Name { get; set; } public object Value { get; set; } public ParameterDirection ParameterDirection { get; set; } public OracleDbType? DbType { get; set; } public int? Size { get; set; } public IDbDataParameter AttachedParam { get; set; }
} /// <summary>
/// construct a dynamic parameter bag
/// </summary>
public OracleDynamicParameters()
{
} /// <summary>
/// construct a dynamic parameter bag
/// </summary>
/// <param name="template">can be an anonymous type or a DynamicParameters bag</param>
public OracleDynamicParameters(object template)
{
AddDynamicParams(template);
} /// <summary>
/// Append a whole object full of params to the dynamic
/// EG: AddDynamicParams(new {A = 1, B = 2}) // will add property A and B to the dynamic
/// </summary>
/// <param name="param"></param>
public void AddDynamicParams(
#if CSHARP30
object param
#else
dynamic param
#endif
)
{
var obj = param as object;
if (obj != null)
{
var subDynamic = obj as OracleDynamicParameters;
if (subDynamic == null)
{
var dictionary = obj as IEnumerable<KeyValuePair<string, object>>;
if (dictionary == null)
{
templates = templates ?? new List<object>();
templates.Add(obj);
}
else
{
foreach (var kvp in dictionary)
{
#if CSHARP30
Add(kvp.Key, kvp.Value, null, null, null);
#else
Add(kvp.Key, kvp.Value);
#endif
}
}
}
else
{
if (subDynamic.parameters != null)
{
foreach (var kvp in subDynamic.parameters)
{
parameters.Add(kvp.Key, kvp.Value);
}
} if (subDynamic.templates != null)
{
templates = templates ?? new List<object>();
foreach (var t in subDynamic.templates)
{
templates.Add(t);
}
}
}
}
} /// <summary>
/// Add a parameter to this dynamic parameter list
/// </summary>
/// <param name="name"></param>
/// <param name="value"></param>
/// <param name="dbType"></param>
/// <param name="direction"></param>
/// <param name="size"></param>
public void Add(
#if CSHARP30
string name, object value, DbType? dbType, ParameterDirection? direction, int? size
#else
string name, object value = null, OracleDbType? dbType = null, ParameterDirection? direction = null, int? size = null
#endif
)
{
parameters[Clean(name)] = new ParamInfo() { Name = name, Value = value, ParameterDirection = direction ?? ParameterDirection.Input, DbType = dbType, Size = size };
} private static string Clean(string name)
{
if (!string.IsNullOrEmpty(name))
{
switch (name[0])
{
case '@':
case ':':
case '?':
return name.Substring(1);
}
}
return name;
} void SqlMapper.IDynamicParameters.AddParameters(IDbCommand command, SqlMapper.Identity identity)
{
AddParameters(command, identity);
} /// <summary>
/// Add all the parameters needed to the command just before it executes
/// </summary>
/// <param name="command">The raw command prior to execution</param>
/// <param name="identity">Information about the query</param>
protected void AddParameters(IDbCommand command, SqlMapper.Identity identity)
{
if (templates != null)
{
foreach (var template in templates)
{
var newIdent = identity.ForDynamicParameters(template.GetType());
Action<IDbCommand, object> appender; lock (paramReaderCache)
{
if (!paramReaderCache.TryGetValue(newIdent, out appender))
{
appender = SqlMapper.CreateParamInfoGenerator(newIdent, false, false);
paramReaderCache[newIdent] = appender;
}
} appender(command, template);
}
} foreach (var param in parameters.Values)
{
string name = Clean(param.Name);
bool add = !((OracleCommand)command).Parameters.Contains(name);
OracleParameter p;
if (add)
{
p = ((OracleCommand)command).CreateParameter();
p.ParameterName = name;
}
else
{
p = ((OracleCommand)command).Parameters[name];
}
var val = param.Value;
p.Value = val ?? DBNull.Value;
p.Direction = param.ParameterDirection;
var s = val as string;
if (s != null)
{
if (s.Length <= 4000)
{
p.Size = 4000;
}
}
if (param.Size != null)
{
p.Size = param.Size.Value;
}
if (param.DbType != null)
{
p.OracleDbType = param.DbType.Value;
}
if (add)
{
command.Parameters.Add(p);
}
param.AttachedParam = p;
}
} /// <summary>
/// All the names of the param in the bag, use Get to yank them out
/// </summary>
public IEnumerable<string> ParameterNames
{
get
{
return parameters.Select(p => p.Key);
}
} /// <summary>
/// Get the value of a parameter
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="name"></param>
/// <returns>The value, note DBNull.Value is not returned, instead the value is returned as null</returns>
public T Get<T>(string name)
{
var val = parameters[Clean(name)].AttachedParam.Value;
if (val == DBNull.Value)
{
if (default(T) != null)
{
throw new ApplicationException("Attempting to cast a DBNull to a non nullable type!");
}
return default(T);
}
return (T)val;
}
}

希望对大家有所帮忙,谢谢!
dapper支持oracle游标的更多相关文章
- 如何让dapper支持oracle游标呢?
Dapper是一个轻型的ORM类.它有啥优点.缺点相信很多朋友都知道了,园里也有很多朋友都有相关介绍,这里就不多废话. 如果玩过Oracle都知道,存储过程基本都是通过游标返回数据的,但是dapper ...
- Dapper连接Oracle
Dapper连接Oracle去年写过了篇博客,名字叫:让dapper支持Oracle 网址:http://www.cnblogs.com/ushou/archive/2012/09/28/270690 ...
- .NET Core中使用Dapper操作Oracle存储过程最佳实践
为什么说是最佳实践呢?因为在实际开发中踩坑了,而且发现网上大多数文章给出的解决方法都不能很好地解决问题.尤其是在获取类型为OracleDbType.RefCursor,输出为:ParameterDir ...
- NET Core中使用Dapper操作Oracle存储过程
.NET Core中使用Dapper操作Oracle存储过程最佳实践 为什么说是最佳实践呢?因为在实际开发中踩坑了,而且发现网上大多数文章给出的解决方法都不能很好地解决问题.尤其是在获取类型为Or ...
- Dapper 封装oracle底层访问数据库
如下代码,修改成只支持oracle: using System; using System.Collections.Generic; using System.Data; using System.L ...
- Oracle游标介绍
Oracle游标使用详解: 游标: 用来查询数据库,获取记录集合(结果集)的指针,我们所说的游标通常是指显式游标,因此从现在起没有特别指明的情况,我们所说的游标都是指显式游标.要在程序中使用游标,必须 ...
- Oracle 游标示例,带异常处理
Oracle游标示例一则,带异常处理. DECLARE CURSOR c_dl IS SELECT ID, NSRSBH, WSPZXH, ZXYY_DM, HZRQ, SWJG_DM, GXSJ F ...
- Oracle游标带参数
Oracle游标是可以带参数的,而SqlServer的游标就不可以了 create or replace procedure a as cursor b(c_id int)is select * fr ...
- BI测试工具之跨数据库数据对比,支持oracle,sqlserver
应用场景: 本周在进行SIT,我帮助仅有的一个测试妹妹对部分表进行数据质量验证,第一步需要做的就是比对source与stage表的table definition 与 数据内容的一致性. 本项目使用的 ...
随机推荐
- ASPF简介
ASPF是一种应用层状态检测技术,它通过与NAT和ALG等技术的组合应用,实现对应用层协议状态的处理和检测. 1.1 产生背景 随着计算机技术和网络技术的普及,网络安全问题也越来越得到关注.防火墙作 ...
- atitit.java方法属性赋值and BeanUtils 1.6.1 .copyProperty的bug
atitit.java分配给属性值方法and BeanUtils 1.6.1 .copyProperty的bug 1. core.setProperty(o, "materialId&quo ...
- 用XAML做网页!!—开篇
原文:用XAML做网页!!-开篇 这几日一直没发表新文章,一来是因为事比较多,二来就是我在研究使用XAML挑战传统HTML来做网页,这很可能是在全球的首次尝试,至少我从未找到任何可供参考的相关资料. ...
- excel单元格中批量加入固定字符
excel单元格前怎么批量加字母 现在我要在联系人这列,每个姓名前加入衡阳的首字母简写(HY). 3 在同行上面随便找列,我找D列.输入公式:="HY"&A2. 5 输入后 ...
- Unreal Engine 4 RenderTarget制作Live Camera效果
Unreal Engine 4 RenderTarget制作Live Camera效果 先上效果: Live Camera我不知道怎么翻译.反正意思就是将一个摄影机的Image渲染到一个2D平面上. ...
- tab功能菜单——使用tab之间不同的交换机div
需求:在web实现类型的接口tab标签效应 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvem91eXVqaWUxMTI3/font/5a6L5L2T/fo ...
- Linux下多线程查看工具(pstree、ps、pstack) (转)
1. pstree pstree以树结构显示进程$ pstree -p work | grep adsshd(22669)---bash(22670)---ad_preprocess(4551)-+- ...
- Android 从硬件到应用程序:一步一步爬上去 5 -- 在Frameworks蒂姆层硬件服务
Android Frameworks层提供硬件服务,Android系统APP能够调用这些硬件服务,而硬件则完全控制.实现应有的功能.上一页下一页.为了这一个frameworks高层的应用java接口硬 ...
- C++ Primer 学习笔记_57_类和数据抽象 --管理指针成员
复印控制 --管理指针成员 引言: 包括指针的类须要特别注意复制控制.原因是复制指针时.一个带指针成员的指针类 class HasPtr { public: HasPtr(int *p,int i): ...
- uva 571 素数的性质
给定 两个杯子,容量分别分Ca,Cb, 要我们用这两个瓶子倒来倒去,得到某个瓶子里装有N的水 而且给的数据保证 Cb > N,且Ca,Cb互质 那么我们肯定可以在容量为Cb的杯子里得到N的水 ...