最近接手了一个旧的系统,各种陈旧的问题比较多,其中最棘手的就是操作数据库的部分,具体如下:

  1、核心库是一个最后修改时间为2008年的库,先不说有多陈旧,现在这个库只是一个DLL文件,没有源码,也已经没人知道里面都实现了些啥功能,就算你怀疑数据库读写有问题,也无法验证和调试,反编译出来的源码也没法用。

  2、这个库用的是System.Data.OracleClient操作Oracle,问题很明显,依赖于Oracle客户端,区分32位和64位,一旦客户的Oracle客户端出点问题,系统就歇菜了,而且部署起来也不方便。

  3、操作数据库用的全是拼写SQL语句,对我这种习惯了ORM的人,实在太痛苦了,而且对JSON和流数据的支持也不是很好,这两种数据都需要单独处理,无形中增加了操作数据库的次数。

  明确了问题,也就知道了最终想要达到的效果,具体如下:

  1、有源码,风险可控。

  2、不依赖于Oracle客户端,不区分32位和64位,这个其实Oracle官方已经提供了解决方案,就是ODP.NET,最新版本已经快可以达到前面两个要求,而且提供了NUGET包,引用简单。

  3、既要兼容旧有的DbHelper的操作方式,也要支持ORM的操作方式,一是因为原来代码量过大,不可能快速完全转到ORM,所以必须兼容旧有的操作方式,同时,ORM也是必须的,毕竟自己用着顺手。

  知道了自己想要什么,于是,我就开始找可以做到这个库,功夫不负有心人,最终我找到了深蓝医生的SOD,完全满足我的要求,具体如下:

  1、SOD完全开源,并提供使用指导。

  2、SOD支持最新版本的ODP.NET,并提供了NUGET的获取方式,相当方便。

  3、SOD不仅是一个ORM,还提供了DBHelper形式的数据库操作方式,不仅如此,更神奇的是,SOD支持执行SQL得到实体的操作方式,是不是很像Dapper.NET?

  4、SOD支持现在大部分主流的数据库,以后要换库也是无缝对接。

  5、客户反馈旧系统如果打开十几分钟没有操作,界面就会卡死,关了重新开,软件依然用不了,必须重启操作系统才能恢复正常,换了SOD之后,这个问题神奇的被修复了,看来真的是数据库读写有问题。不过也从侧面说明旧系统的异常处理和日志机制有些问题,这么严重的问题,既没有抛出异常,也没有记录日志,看来需要填的坑还是有一些的。

  说了这么多废话,还是要来点干货,把我写的兼容旧系统的基于SOD的DbHelper给大家看看,写的不好,还希望多多指教,最后总结一句:

  人生苦短,我用SOD,蜜!

  SOD源码地址:
  OSC@GIThttp://git.oschina.net/dxzyx/SOD
  Codeplex:http://pwmis.codeplex.com/SourceControl/latest
  GITHUB:https://github.com/znlgis/PDF.NET-SOD
  NUGET地址:https://www.nuget.org/profiles/znlgis

 using System.Collections.Generic;
using PWMIS.DataMap.Entity;
using PWMIS.DataProvider.Adapter;
using PWMIS.DataProvider.Data; namespace ComnLib
{
/// <summary>
/// 数据库访问类
/// </summary>
public class DbHelper
{
#region 静态部分 private static AdoHelper _instance;
/// <summary>
/// 获取或者设置默认的数据库操作对象,如果未设置将采用默认的配置进行实例化数据库操作对象。
/// 支持读写分离模式
/// </summary>
public static AdoHelper Instance
{
get
{
if (_instance == null)
{
var dataConInfomation = new DcicDbConnInfo();
DcicComnLib.Sys_GetOracleSetting(ref dataConInfomation); _instance =
MyDB.GetDBHelperByProviderString(
"PWMIS.DataProvider.Data.OracleDataAccess.Oracle,PWMIS.OracleClient",
$"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST={dataConInfomation.Ip})(PORT={dataConInfomation.Port}))(CONNECT_DATA=(SID={dataConInfomation.Sid})));User Id={dataConInfomation.UserId};Password={dataConInfomation.Pwd};");
} return _instance;
}
} /// <summary>
/// 增加一条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="model"></param>
/// <returns></returns>
public static bool Insert<T>(T model) where T : EntityBase, new()
{
var query = new EntityQuery<T>(Instance);
var result = query.Insert(model); return result == ;
} /// <summary>
/// 执行一个无返回值的OQL语句
/// </summary>
/// <param name="oql"></param>
/// <returns></returns>
public static bool ExecuteOql(OQL oql)
{
var result = EntityQuery.ExecuteOql(oql, Instance);
return result == ;
} /// <summary>
/// 删除一条记录,必须有主键
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static bool Delete<T>(T model) where T : EntityBase, new()
{
var query = new EntityQuery<T>(Instance);
var result = query.Delete(model); return result == ;
} /// <summary>
/// 更新一条记录,必须有主键
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static bool Update<T>(T model) where T : EntityBase, new()
{
var query = new EntityQuery<T>(Instance);
var result = query.Update(model); return result == ;
} /// <summary>
/// 使用OQL查询多条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="oql"></param>
/// <returns></returns>
public static List<T> QueryList<T>(OQL oql) where T : EntityBase, new()
{
var query = new EntityQuery<T>(Instance);
return query.GetList(oql);
} /// <summary>
/// 使用GOQL查询多条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="oql"></param>
/// <returns></returns>
public static List<T> QueryList<T>(GOQL<T> oql) where T : EntityBase, new()
{
return oql.ToList(Instance);
} /// <summary>
/// 使用OQL查询一条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="oql"></param>
/// <returns></returns>
public static T QueryObject<T>(OQL oql) where T : EntityBase, new()
{
var query = new EntityQuery<T>(Instance); return query.GetObject(oql);
} /// <summary>
/// 使用GOQL查询一条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="oql"></param>
/// <returns></returns>
public static T QueryObject<T>(GOQL<T> oql) where T : EntityBase, new()
{
return oql.ToObject(Instance);
} /// <summary>
/// 使用SQL查询多条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sql"></param>
/// <returns></returns>
public static List<T> QueryList<T>(string sql) where T : EntityBase, new()
{
return EntityQuery<T>.QueryList(Instance.ExecuteDataReader(sql));
} /// <summary>
/// 使用SQL查询一条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sql"></param>
/// <returns></returns>
public static T QueryObject<T>(string sql) where T : EntityBase, new()
{
return EntityQuery<T>.QueryObject(Instance.ExecuteDataReader(sql));
} /// <summary>
/// 用于复杂查询的映射
/// </summary>
/// <param name="sql"></param>
/// <returns>实体数据容器</returns>
public static DataReaderMapper QueryMapper(string sql)
{
return Instance.ExecuteMapper(sql);
} #endregion #region 动态部分 /// <summary>
/// 获取各种数据库的DbHelper
/// </summary>
/// <param name="providerName"></param>
/// <param name="connectionString"></param>
/// <returns></returns>
public AdoHelper GetHelper(string providerName, string connectionString)
{
return MyDB.GetDBHelperByProviderString(providerName,
connectionString);
} /// <summary>
/// 获取Oracle数据库的DbHelper
/// </summary>
/// <param name="dataConInfomation"></param>
/// <returns></returns>
public AdoHelper GetHelper(DcicDbConnInfo dataConInfomation)
{
return MyDB.GetDBHelperByProviderString(
"PWMIS.DataProvider.Data.OracleDataAccess.Oracle,PWMIS.OracleClient",
$"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST={dataConInfomation.Ip})(PORT={dataConInfomation.Port}))(CONNECT_DATA=(SID={dataConInfomation.Sid})));User Id={dataConInfomation.UserId};Password={dataConInfomation.Pwd};");
} /// <summary>
/// 增加一条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="model"></param>
/// <param name="db"></param>
/// <returns></returns>
public bool Insert<T>(T model, AdoHelper db) where T : EntityBase, new()
{
var query = new EntityQuery<T>(db);
var result = query.Insert(model); return result == ;
} /// <summary>
/// 执行一个无返回值的OQL语句
/// </summary>
/// <param name="oql"></param>
/// <param name="db"></param>
/// <returns></returns>
public bool ExecuteOql(OQL oql, AdoHelper db)
{
var result = EntityQuery.ExecuteOql(oql, db); return result == ;
} /// <summary>
/// 删除一条记录,必须有主键
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="model"></param>
/// <param name="db"></param>
/// <returns></returns>
public bool Delete<T>(T model, AdoHelper db) where T : EntityBase, new()
{
var query = new EntityQuery<T>(db);
var result = query.Delete(model); return result == ;
} /// <summary>
/// 更新一条记录,必须有主键
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="model"></param>
/// <param name="db"></param>
/// <returns></returns>
public bool Update<T>(T model, AdoHelper db) where T : EntityBase, new()
{
var query = new EntityQuery<T>(db);
var result = query.Update(model); return result == ;
} /// <summary>
/// 用GOQL查询多条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="oql"></param>
/// <param name="db"></param>
/// <returns></returns>
public List<T> QueryList<T>(GOQL<T> oql, AdoHelper db) where T : EntityBase, new()
{
return oql.ToList(db);
} /// <summary>
/// 用GOQL查询一条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="oql"></param>
/// <param name="db"></param>
/// <returns></returns>
public T QueryObject<T>(GOQL<T> oql, AdoHelper db) where T : EntityBase, new()
{
return oql.ToObject(db);
} /// <summary>
/// 用OQL查询多条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="oql"></param>
/// <param name="db"></param>
/// <returns></returns>
public List<T> QueryList<T>(OQL oql, AdoHelper db) where T : EntityBase, new()
{
var query = new EntityQuery<T>(db);
return query.GetList(oql);
} /// <summary>
/// 用OQL查询一条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="oql"></param>
/// <param name="db"></param>
/// <returns></returns>
public T QueryObject<T>(OQL oql, AdoHelper db) where T : EntityBase, new()
{
var query = new EntityQuery<T>(db);
return query.GetObject(oql);
} /// <summary>
/// 用SQL查询多条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sql"></param>
/// <param name="db"></param>
/// <returns></returns>
public List<T> QueryList<T>(string sql, AdoHelper db) where T : EntityBase, new()
{
return EntityQuery<T>.QueryList(db.ExecuteDataReader(sql));
} /// <summary>
/// 用SQL查询一条记录
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sql"></param>
/// <param name="db"></param>
/// <returns></returns>
public T QueryObject<T>(string sql, AdoHelper db) where T : EntityBase, new()
{
return EntityQuery<T>.QueryObject(db.ExecuteDataReader(sql));
} /// <summary>
/// 用于复杂查询的映射
/// </summary>
/// <param name="sql"></param>
/// <param name="db"></param>
/// <returns>实体数据容器</returns>
public DataReaderMapper QueryMapper(string sql, AdoHelper db)
{
return db.ExecuteMapper(sql);
} #endregion
}
}

SOD让你的旧代码焕发青春的更多相关文章

  1. ca33a_demo_c++_新旧代码的兼容char数组与vector_string相互转换

    /*ca33a_demo_c++33_CppPrimer_新旧代码的兼容_txwtech旧代码:数组和c风格字符串新代码:vector和string相互转换:c风格字符串<- ->stri ...

  2. [实用指南]如何使您的旧代码库(遗留代码)符合MISRA C 2012编码规范?

    重用旧代码是现实,但是在安全关键型软件项目中重用旧代码并实现MISRA C 2012的完全合规性是艰巨的任务. 最初的MISRA原则是为了在开发代码时应用而创建的,即使文档本身也有警告: " ...

  3. 请注意更新TensorFlow 2.0的旧代码

    TensorFlow 2.0 将包含许多 API 变更,例如,对参数进行重新排序.重新命名符号和更改参数的默认值.手动执行所有这些变更不仅枯燥乏味,而且容易出错.为简化变更过程并让您尽可能顺畅地过渡到 ...

  4. VS重新生成后仍然执行旧代码

    主要可能有以下三种情况: 1,生成的代码放错位置了,在iis中浏览打开网站目录,确保路径正确,不要自以为是. 2,页面和动态库不匹配,都要更新. 3,清除浏览器的缓存.

  5. 迁移32位下的旧代码到64位sever遇到过的两个很诡异的问题

    一个是GetHashCode,这个方法是返回一个int值,在32位系统里,都是正值,但在64位系统里会返回负值. 另一个问题是DataTable的Sort属性,在没有显示写明升序或降序的情况下,在32 ...

  6. .NET ORM 的 “SOD蜜”--零基础入门篇

    PDF.NET SOD框架不仅仅是一个ORM,但是它的ORM功能是独具特色的,我在博客中已经多次介绍,但都是原理性的,可能不少初学的朋友还是觉得复杂,其实,SOD的ORM是很简单的.下面我们就采用流行 ...

  7. iOS 代码规范

    1 目的 统一规范XCode编辑环境下Objective-C.swift的编码风格和标准 2 适用范围 适用于所有用Objective-C,swift语言开发的项目. 3 编码规范 3.1 文件 项目 ...

  8. ReactiveCocoa代码实践之-RAC网络请求重构

    前言 RAC相比以往的开发模式主要有以下优点:提供了统一的消息传递机制:提供了多种奇妙且高效的信号操作方法:配合MVVM设计模式和RAC宏绑定减少多端依赖. RAC的理论知识非常深厚,包含有FRP,高 ...

  9. CSS代码重构与优化之路

    作者:@狼狼的蓝胖子 网址:http://www.cnblogs.com/lrzw32/p/5100745.html 写CSS的同学们往往会体会到,随着项目规模的增加,项目中的CSS代码也会越来越多, ...

随机推荐

  1. PHP中模拟JSONArray

    前面整理过一篇文章,描述php中的array与json的array和object的转换关系.http://www.cnblogs.com/x3d/p/php-json-array-object-typ ...

  2. jQuery版AJAX简易封装

    开发过程中,AJAX的应用应该说非常频繁,当然,jQuery的AJAX函数已经非常好用,但是小编还是稍微整理下,方便不同需求下,可以简化输入参数,下面是实例代码: $(function(){ /** ...

  3. 每次新建项目出现appcompat_v7 解决方法

    ADT升级版本后每次新建项目出现appcompat_v7 , 解决方案如下 问题生成:

  4. SharePoint文档库文件夹特殊字符转义

    当我们在SharePoint网站文档库中新建文件夹时包含了~ " # % & * : < > ? / \ { | }字符时(一共15个), 或者以.开头或者结束,或者包含 ...

  5. CALayer的transform属性

    先来与View比较一下 View:transform -> CGAffineTransformRotate... layer:transform -> CATransform3DRotat ...

  6. FlashBuilder4安装SVN插件步骤

    1. 选择菜单 帮助–> 安装新软件 2. 在使用里键入地址:  http://subclipse.tigris.org/update_1.6.x并点击添加 在Subclipse栏里选择带有Re ...

  7. luke使用

    Luke介绍 Luke是一个方便的索引查看和诊断工具,可以访问Lucene构建的索引文件,显示和修改某些索引内容.能提供: 通过document编号或term浏览索引 查看document内容,可复制 ...

  8. 几大排序算法的Java实现

    很多的面试题都问到了排序算法,中间的算法和思想比较重要,这边我选择了5种常用排序算法并用Java进行了实现.自己写一个模板已防以后面试用到.大家可以看过算法之后,自己去实现一下. 1.冒泡排序:大数向 ...

  9. 查看Oracle执行计划

    1.PL/SQL解释计划窗口 优点:方面 缺点:看到信息有限 2.explain_plan for 针对某个句子优化较方便 3.sqlplus Sqlplus里输入命令: set autotrace ...

  10. 【推荐】CentOS安装Subversion-1.8.11+HTTP协议支持配置

    注:以下所有操作均在CentOS 6.5 x86_64位系统下完成. 我们需要搭建一个自己的SVN服务器. 此外,搭建好的SVN服务器除了需要支持svn协议外,最好还需要支持HTTP协议和HTTPS协 ...