SOD让你的旧代码焕发青春
最近接手了一个旧的系统,各种陈旧的问题比较多,其中最棘手的就是操作数据库的部分,具体如下:
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@GIT:http://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让你的旧代码焕发青春的更多相关文章
- ca33a_demo_c++_新旧代码的兼容char数组与vector_string相互转换
/*ca33a_demo_c++33_CppPrimer_新旧代码的兼容_txwtech旧代码:数组和c风格字符串新代码:vector和string相互转换:c风格字符串<- ->stri ...
- [实用指南]如何使您的旧代码库(遗留代码)符合MISRA C 2012编码规范?
重用旧代码是现实,但是在安全关键型软件项目中重用旧代码并实现MISRA C 2012的完全合规性是艰巨的任务. 最初的MISRA原则是为了在开发代码时应用而创建的,即使文档本身也有警告: " ...
- 请注意更新TensorFlow 2.0的旧代码
TensorFlow 2.0 将包含许多 API 变更,例如,对参数进行重新排序.重新命名符号和更改参数的默认值.手动执行所有这些变更不仅枯燥乏味,而且容易出错.为简化变更过程并让您尽可能顺畅地过渡到 ...
- VS重新生成后仍然执行旧代码
主要可能有以下三种情况: 1,生成的代码放错位置了,在iis中浏览打开网站目录,确保路径正确,不要自以为是. 2,页面和动态库不匹配,都要更新. 3,清除浏览器的缓存.
- 迁移32位下的旧代码到64位sever遇到过的两个很诡异的问题
一个是GetHashCode,这个方法是返回一个int值,在32位系统里,都是正值,但在64位系统里会返回负值. 另一个问题是DataTable的Sort属性,在没有显示写明升序或降序的情况下,在32 ...
- .NET ORM 的 “SOD蜜”--零基础入门篇
PDF.NET SOD框架不仅仅是一个ORM,但是它的ORM功能是独具特色的,我在博客中已经多次介绍,但都是原理性的,可能不少初学的朋友还是觉得复杂,其实,SOD的ORM是很简单的.下面我们就采用流行 ...
- iOS 代码规范
1 目的 统一规范XCode编辑环境下Objective-C.swift的编码风格和标准 2 适用范围 适用于所有用Objective-C,swift语言开发的项目. 3 编码规范 3.1 文件 项目 ...
- ReactiveCocoa代码实践之-RAC网络请求重构
前言 RAC相比以往的开发模式主要有以下优点:提供了统一的消息传递机制:提供了多种奇妙且高效的信号操作方法:配合MVVM设计模式和RAC宏绑定减少多端依赖. RAC的理论知识非常深厚,包含有FRP,高 ...
- CSS代码重构与优化之路
作者:@狼狼的蓝胖子 网址:http://www.cnblogs.com/lrzw32/p/5100745.html 写CSS的同学们往往会体会到,随着项目规模的增加,项目中的CSS代码也会越来越多, ...
随机推荐
- 《c# 从入门经典》 (第6版) - 变量和表达式
1,程序就是对一系列数据的操作:数据最终是存储在内存中的0和1数据流:我们在桌面上的任何操作都会改变内存中的数据. 2,变量存储在计算机中占用着一定的内存空间 bit: 位,计算机的最小存储单位,存储 ...
- c++ map 使用
. 包含头文件: #include <map> 2. 构造函数: std::map<char,int> first; first[; first[; first[; first ...
- 类型转换和类型相关函数.png
- HTML5应用程序缓存Application Cache
什么是Application Cache HTML5引入了应用程序缓存技术,意味着web应用可进行缓存,并在没有网络的情况下使用,通过创建cache manifest文件,可以轻松的创建离线应用. A ...
- script标签中defer和async属性的区别
这篇文章来源于JS高级程序设计第三版中关于script标签的介绍,结合查阅的资料写下的学习笔记. 向html页面中插入javascript代码的主要方法就是通过script标签.其中包括两种形式,第一 ...
- ArcGIS Engine开发之量测功能
1.距离测量 距离测量时,片段长度通过两点之间距离计算得到,全部长度通过片段长度的和计算得到.主要用到INewLineFeedback和IScreenDisplay两个接口. 1)INewLineFe ...
- Linux2.6内核进程调度系列--scheduler_tick()函数3.更新普通进程的时间片
RT /** * 运行到此,说明进程是普通进程.现在开始更新普通进程的时间片. */ /* 首先递减普通进程的时间片计数器.如果用完,继续执行以下操作 */ if (!--p->time_sli ...
- 【代码笔记】iOS-获得富文本设置以后的文字高度
一,效果图. 二,工程图. 三,代码. RootViewController.h #import <UIKit/UIKit.h> @interface RootViewController ...
- css权威指南--笔记
第1章 css和文档 1,元素:替换元素(img input),非替换元素(大多数span). 2,link:rel(代表关系:stylesheet,候选样式表:alternate styleshee ...
- reborn to freelancer
I want to be a freelancer, so I come back to record all my efforts. I hope this will be a new start ...