周末了比较清闲,把自己的orm框架整理了下,开源了.

  已经做出来的东西通常感觉有些简单,一些新手或许听到"框架"一类的词觉得有些"高深",简单来说orm就是把ado的封装.

在介绍这个框架的第一篇博文,已经把DalBase介绍了一下设计思路,本篇的DBHelper对象也是给dalBase来用的,可以说框架的所有定义对象都是为了它.

这里起名叫DBHelper,因为我也是从写SQLHelper开始的,DBHelper只不过是所有类型对ado操作的各种方法的封装,所以本篇博文希望给c#新手,或是对ado.net认识比较模糊的有一些帮助.

首先DBHelper定义是个抽象的,因为我不知道DalBase 到底要访问哪种数据库,但我知道不管哪中数据库都会有链接字符串,那我就要求,必须要有连接字符串.

public DbHelperBase(string connStr)
{
_ConnStr = connStr;
}

DbHelper是个抽象的,那它的成员必然就不能有具体对象.

那就把ado.net常用的对象定义出来.(如果你是初学者,我的建议是 用到哪个对象再去定义,否则到后期自己都不知道定义它干啥呢)

        protected abstract DbConnection DBConnectionObj { get; }
protected abstract DbCommand DbCommandObj { get; }
protected abstract DbDataAdapter DbDataAdapterObj { get; }
protected DbTransaction DbTransObj; public DbConnection CurrentConnection
{
get
{
return DBConnectionObj;
}
}

说明一下,为什么事务对象不是抽象的,因为事务对象始终是有DbConnection来创建的,我不用知道它具体是什么类型.

DbConnection 对象public也是为了扩展其它功能而存在的.

定义了是否事务的变量,所有ado操作都会判断当前是否处于事务的标记.

bool _IsTrans = false;

初学.net的朋友,应该都会有一个SQLHelper的类,我也曾经看过都大同小异,而且普遍都没有事务的实现,如果你中枪了,那么恭喜你,你即将会改变你sqlHelper的实现.

如下代码:

     /// <summary>
/// 执行一条指定命令类型(SQL语句或存储过程等)的SQL语句,返回所影响行数
/// </summary>
public int ExecNonQuery(string sqlText, CommandType cmdType, params DbParameter[] param)
{
using (SqlConnection conn = new SqlConnection(_ConnStr))
{
using (SqlCommand cmd = new SqlCommand(sqlText, conn))
{
cmd.CommandType = cmdType;
if (param != null)
cmd.Parameters.AddRange(param);
conn.Open();
return cmd.ExecuteNonQuery();
}
}
}

以上代码看起来是没什么问题,但如果要启用事务的话想想是否可以实现呢?

如果说改造一下加上事务的代码就行的话

如下:

 SqlTransaction tran = conn.BeginTransaction();
cmd.Transaction = tran;

这样显然是错的,因为我们往往多条执行语句通常是分多次调用 ExecNonQuery() 方法的.

这样的一个ado方法的封装显然是不合理的.

如果多个增删改查(注意:查询也可能在是事务里)的方法,在一个事务里,那么必须是一个数据库连接(Connection)

这就是为什么把那三个对象定义到外面的原因之一了,最重要的原因是我需要子类去重写它.

下面看看我的实现:

        /// <summary>
/// 打开连接,如果已经打开则什么都不执行了
/// </summary>
void OpenConnection()
{
if (DBConnectionObj.State != ConnectionState.Open)
{
DBConnectionObj.ConnectionString = _ConnStr;
DBConnectionObj.Open();
}
}
        /// <summary>
/// 给当前DbCommand对象赋值,并且OpenConnection();
/// </summary>
void SetCommandAndOpenConnect(string sqlText, CommandType cmdType, params DbParameter[] param)
{
//按说赋值Connection,CommandType,是不用多次赋值的
DbCommandObj.CommandType = cmdType;
DbCommandObj.Connection = DBConnectionObj;
DbCommandObj.Parameters.Clear();
if (param != null)
{
DbCommandObj.Parameters.AddRange(param);
}
DbCommandObj.CommandText = sqlText;
OpenConnection();
}
        /// <summary>
/// 执行一条指定命令类型(SQL语句或存储过程等)的SQL语句,返回所影响行数
/// </summary>
public int ExecNonQuery(string sqlText, CommandType cmdType, params DbParameter[] param)
{
try
{
SetCommandAndOpenConnect(sqlText, cmdType, param);
return DbCommandObj.ExecuteNonQuery();
}
catch (Exception ex)
{
throw ex;
}
finally
{
CloseConnect();
}
}

看到这三个方法或许对于初学者会感到迷茫了,没有看到任何有关事务的代码呢,兜个圈子,现在想象一下如果加事务的话,需要做什么?

我们先从理论上认识一下,事务处理的流程

1.指定事务是哪个Connection

2.Command的事务对象指定到该事务.

3.Open()

4.提交或回滚(我是能写汉字的地方绝不写拼音)

5.关闭连接.

继续说这几个方法,为什么定义SetCommandAndOpenConnect 和 OpenConnection 这两个方法,本着尽量减少重复代码的原则.仅此而已.

既然Connection和Command都已经定义到方法外了,那就是说我只要再执行Command.ExecuteNonQuery()方法前,给他们赋值就行了.

也就是开始事务只需要给这个两个对象赋值即可

事务的相关代码如下:

        /// <summary>
/// 开始执行事务
/// </summary>
public void TransStart()
{
OpenConnection();
DbTransObj = DBConnectionObj.BeginTransaction();
DbCommandObj.Transaction = DbTransObj;
_IsTrans = true;
}
/// <summary>
/// 事务提交
/// </summary>
public void TransCommit()
{
_IsTrans = false;
DbTransObj.Commit();
CloseConnect();
}
/// <summary>
/// 事务回滚
/// </summary>
public void TransRollback()
{
_IsTrans = false;
DbTransObj.Rollback();
CloseConnect();
}

这就是事务的方法了.

最后一个CloseConnect()方法,差点把它遗忘了

        /// <summary>
/// 关闭连接,如果没有开始事务或连接打开时才关闭
/// </summary>
void CloseConnect()
{
if (!_IsTrans)
{
if (DBConnectionObj.State == ConnectionState.Open)
{
DBConnectionObj.Close();
DBConnectionObj.Dispose();
}
}
}

当开始事务时,连接是不能关的.只有提交了或回滚了才会把当前连接断掉.

到这里其实DbHelper的设计基本完成,再贴一下关于查询的几个方法,和执行类似就不解释了.

     /// <summary>
/// 获得首行首列
/// </summary>
public object GetScalar(string sqlText, CommandType cmdType, params DbParameter[] param)
{
try
{
SetCommandAndOpenConnect(sqlText, cmdType, param);
return DbCommandObj.ExecuteScalar(); }
catch (Exception ex)
{
throw ex;
}
finally
{
CloseConnect();
}
}
     /// <summary>
/// 执行一条SQL语句返回DataSet对象
/// </summary>
public DataSet GetDataSet(string sqlText, CommandType cmdType, params DbParameter[] param)
{
try
{
SetCommandAndOpenConnect(sqlText, cmdType, param);
DbDataAdapterObj.SelectCommand = DbCommandObj;
DataSet ds = new DataSet();
DbDataAdapterObj.Fill(ds);
return ds;
}
catch (Exception ex)
{
throw ex;
}
finally
{
CloseConnect();
}
}      /// <summary>
/// 获得DataReader对象
/// </summary>
public DbDataReader GetDataReader(string sqlText, CommandType cmdType, params DbParameter[] param)
{
try
{
SetCommandAndOpenConnect(sqlText, cmdType, param);
CommandBehavior cmdBehavior = CommandBehavior.CloseConnection;
if (_IsTrans)
{
cmdBehavior = CommandBehavior.Default;
}
DbDataReader dbReader = DbCommandObj.ExecuteReader(cmdBehavior);
return dbReader;
}
catch (Exception ex)
{
throw ex;
}
finally
{
//DataReader用dbReader对象来关闭
//CloseConnect();
}
}

这里需要注意的是关于返回DataReader对象时不能关闭Connect,和 cmdBehavior 的赋值.

好了,到这DBHelper的设计和核心代码已经全部实现了.

试想一下我现在要完成SQLServerHelper的实现需要做的是什么?

当然只要实现父类的那几个抽象属性就行了.

代码如下:

 public class SQLHelper : DbHelperBase
{
public SQLHelper(string connStr)
: base(connStr)
{ } SqlConnection _DBConnectionObj;
SqlCommand _DbCommandObj;
SqlDataAdapter _DbDataAdapterObj; protected override DbConnection DBConnectionObj
{
get
{
//SqlBulkCopy aa = new SqlBulkCopy(new SqlConnection());
if (_DBConnectionObj == null)
{
_DBConnectionObj = new SqlConnection(_ConnStr);
}
return _DBConnectionObj;
}
} protected override DbCommand DbCommandObj
{
get
{
if (_DbCommandObj == null)
{
_DbCommandObj = new SqlCommand();
}
return _DbCommandObj;
}
} protected override DbDataAdapter DbDataAdapterObj
{
get
{
if (_DbDataAdapterObj == null)
{
_DbDataAdapterObj = new SqlDataAdapter();
}
return _DbDataAdapterObj;
}
} }

OracleHelper,oledbhelper,SQLiteHelper,就不贴代码了.

转载建议标明出处(我从来不强迫别人做我管不了的事).

整个框架的源码在介绍框架的第一篇博文里有.

欢迎吐槽,点赞,建议,批评,指正,抄袭.

c# 轻量级 ORM 框架 之 DBHelper 实现 (三)的更多相关文章

  1. 轻量级ORM框架初探-Dapper与PetaPoco的基本使用

    一.EntityFramework EF是传统的ORM框架,也是一个比较重量级的ORM框架.这里仍然使用EF的原因在于为了突出轻量级ORM框架的性能,所谓有对比才有更优的选择. 1.1 准备一张数据库 ...

  2. c# 轻量级ORM框架 实现(一)

    发布一个自己写的一个轻量级ORM框架,本框架设计期初基于三层架构.所以从命名上来看,了解三层的朋友会很好理解. 设计该框架的目的:不想重复的写增删改查,把精力放到功能实现上. 发布改框架的原因:希望给 ...

  3. 轻量级ORM框架 QX_Frame.Bantina(二、框架使用方式介绍)

    轻量级ORM框架QX_Frame.Bantina系列讲解(开源) 一.框架简介 http://www.cnblogs.com/qixiaoyizhan/p/7417467.html 二.框架使用方式介 ...

  4. 轻量级ORM框架 QX_Frame.Bantina(一、框架简介)

    轻量级ORM框架QX_Frame.Bantina系列讲解(开源) 一.框架简介 http://www.cnblogs.com/qixiaoyizhan/p/7417467.html 二.框架使用方式介 ...

  5. .NET轻量级ORM框架Dapper入门精通

    一.课程介绍 本次分享课程包含两个部分<.NET轻量级ORM框架Dapper修炼手册>和<.NET轻量级ORM框架Dapper葵花宝典>,阿笨将带领大家一起领略轻量级ORM框架 ...

  6. 轻量级ORM框架Dapper应用一:Dapper安装

    一.Dapper简介 Dapper是一款轻量级ORM框架,为解决网站访问流量极高而产生的性能问题而构造,主要通过执行TSQL表达式而实现数据库的CQRS. 如果你在项目中遇到性能访问问题,选择Dapp ...

  7. C# 性能优化 之 秒表 Stopwatch。 Dapper一个和petapoco差不多的轻量级ORM框架

    Sweet小马 小马同学的编程日记. C# 性能优化 之 秒表 Stopwatch. 生词解释:Diagnostics[,daɪəg'nɑstɪks] n.诊断学 using System.Diagn ...

  8. 分享自己写的基于Dapper的轻量级ORM框架~

    1.说明 本项目是一个使用.NET Standard 2.0开发的,基于 Dapper 的轻量级 ORM 框架,包含基本的CRUD以及根据表达式进行一些操作的方法,目前只针对单表,不包含多表连接操作. ...

  9. 轻量级ORM框架 Bankinate

    [前言] 前面讲过ORM的前世今生,对ORM框架不了解的朋友可以参考博文:https://www.cnblogs.com/7tiny/p/9551754.html 今天,我们主要通过设计一款轻量级的O ...

随机推荐

  1. Asp.net 访问数据库的几种方式

    ASP.NET中连接数据库的各种方法 连接SQL数据库的方法:(一).在Web.Config中创建连接字符串:1.<add name="ConnectionString" c ...

  2. YII 快速创建项目GII

    Yii 是一个基于组件.纯OOP的.用于开发大型 Web 应用的高性能PHP框架. 它将Web编程中的可重用性发挥到极致,能够显著加速开发进程 .Yii适合大流量的应用,如门户.BBS.CMS及B2B ...

  3. 使用Selenium+appium进行App测试

    1. 启动安卓虚拟机.

  4. LoadRunner error -27257

    检查点函数 web_reg_find("Search=body", "savecount=num", "Text=test1", LAST) ...

  5. Epic - Seed Number

    Find the seed of a number. Eg : 1716 = 143*1*4*3 =1716 so 143 is the seed of 1716. find all possible ...

  6. win7 提示"Windows 无法连接到System Event Notification Service服务......"的解决办法

    登录win7系统,突然出现如图1的提示,无线网络中断,不能上网,多次插拔无线网卡问题依然. 图1 解决过程如下: 1.检查网卡硬件状况,在设备管理器中查看网卡现象正常,排除网卡硬件故障. 2.查看服务 ...

  7. 黑马程序员——OC与C语言的异同比较

    1.  文件介绍:Objective-C 也使用头文件(header files),后缀为 .h, 但使用 .m(即 message, 其他面向对象编程语言也叫 method),作为源文件的后缀.   ...

  8. 最好的10本适用于初学者阅读的javaScript和jQuery书籍

    现在有许多方式学习新的内容,但是对于刚开始学习和寻找真正沉迷其中的平和状态的人而言,经典的纸质书籍依旧是首选.我发现阅读一本纸质书籍会让自己远离那些在使用电脑和平板时出现的令人不安的情绪.电子书和播客 ...

  9. NServiceBus教程-持久化配置

    当配置在NServiceBus v5持久性,秩序是非常重要的.最后赢得持久性配置选项.我们看看一些例子. 示例1 在本例中最后一个配置选项将会覆盖前面的所有选项. v5.2 v5.0 编辑 var c ...

  10. 创建并使用Windows Azure虚拟机模板

    在现实的IaaS应用中,往往会创建自己的虚拟机映像模板,以满足快速应用部署的目标,如预先配置好某些应用.管理与监控管理等. 1.登录到Windows Azure Dashboard中创建一个做为模板的 ...