如何让dapper支持oracle游标呢?
2015-11-18 23:57
585 查看
Dapper是一个轻型的ORM类。它有啥优点、缺点相信很多朋友都知道了,园里也有很多朋友都有相关介绍,这里就不多废话。
如果玩过Oracle都知道,存储过程基本都是通过游标返回数据的,但是dapper原生操作游标会报异常,具体异常信息因为现在没有环境就不截图了。
以上是实际项目的代码片段,通过游标获取查询数据。
那如何去解决这个游标问题呢?就是这个OracleDynamicParameters类,全部内容如下:
希望对大家有所帮忙,谢谢!
如果玩过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; } }
希望对大家有所帮忙,谢谢!
相关文章推荐
- oracle去重等基础问题
- ORACLE ORA22922 不存在的LOB值解决方法
- Oracle ubuntu 下快速安装
- Oracle Linux: Error "Missing Or Invalid IPv4 Prefix '0' On Linux Server" (文档 ID 1522095.1)
- 查看Oracle的实例
- Oracle 自定义结构(Record) 记录
- Oracle存储过程中的异常处理
- oracle系统包——dbms_job用法(oracle定时任务)
- PFILE和SPFILE介绍
- ORACLE PL/SQL 字符串函数、数学函数、日期函数
- Navicat V11 连接 oracle 11g 的问题
- oracle添加和查看注释
- J2EE应用中与Oracle数据库的连接
- Oracle 11g DG配置简明版
- Oracle 10g RAC 在Linux下安装经验总结
- oracle 备份:全量、增量、0级、1级、差分、增量
- oracle 中处理 时间 显示为 年 月 日 下午/上午 时 分 秒
- oracle 中clob数据在Java类 里sql处理
- Oracle使用split和splitstr函数批量分隔字符串
- Oracle Packge