上接:[原创] 我的ORM: 开发自己的Data Access Application Block - Part I
4. Database

下面来介绍重中之重:Database,绝大部分的Data Access 操作都集中在这个Abstract Database中。这是一个相对庞大的Class,所以不得不采用Partial Class的方式来编写。

Part I:Field 和Property

这些Field 和Property基本上对应我们前面的Configuraiton。此为我们定义了三个Field 和Property:DbDataAdapter,Connection,_transaction。考虑到垃圾回收,使Database实现IDisposable接口。值得说明一点的是,我们通过Database的DatabaseProviderFactory创建了泛型的DbDataAdapter,DbConnection和Transaction。

  • ConnectionString:string
  • DatabaseProviderFactory:DbProviderFactory
  • DefaultCommandType:CommandType
  • UseCommandBuilder:bool
  • DbParameterNameMapping:IDbParameterNameMapping
  • StoredProcedureNameMapping:IStoredProcedureNameMapping
  • DbDataAdapter:DbDataAdapter
  • Connection: DbConnection
  • Transaction: DbTransaction

Part II: Fill Dataset

很简单,基本上ADO.NET 的基本操作,没什么可值得说的。

Part III Execute 系列

Part IV: Transaction

定义了3个基于Transaction的方法BeginTransaction,Commit和RollBack,使Developer显示地开始和结束一个Transaction,这样他可以很直观地把所需的操作纳入某个Transaction中。

Part V: Update

这一部分花了很多时间和精力,现看Code:

我们来分析一下 public void UpdateData(DataSet dataInfo),这个方法对Data Access操作进行了高度的封装,Developer所做就是把更新过的Dataset传入UpdateData方法,其它的所有操作交给AppBlock来做。要实现这样的功能其实是很麻烦的,要考虑的因素很多:

  • 需要把分析Dataset中DataTable之间的关系,确定先对那个Table 进行操作。
  • Dataset中的数据包含不同DataRowState的记录:Added,Modified,Deleted;需要和Dataset中DataTable之间的关系结合确定不同表,不同DataRowState数据的操作顺序。
  • 使用Stored Procedure进行更新,需要考虑以下的Mapping:DataTable的Name和Stored Procedure Name;不同DataRowVersion的DataRow中的Field和Stored Procedure中的参数名。

我的解决方案是:

为了避免数据库中数据的冲突,我们数据更新的顺序是:Deleted Data->Modified Data->Added Data;考虑到表之间的主子关系,对于Added Data和Modified Data,我们应该先修改Parent Table,后修改Child,而对Deleted Data顺序却恰好相反。由于我们 不应该对DataSet中的Table的数量和关系做出任何假设,我们需要以一种递归的过程完成数据的更新。本着这样一个原则,我们来看我们的实现:

整个过程分3步骤,更新Deleted data.-> 更新Modified data.-> 更新Added data.真正的数据更新集中在UpdateDependentTable这样一个方法中。

通过传入的DataRowState创建一个DataViewRowState变量。对于DataRowState.Added和DataRowState.Modified,通过ParentRelations属性递归地获得并修改Parent Table的数据,然后跟新本Table,最后通过ChildRelations属性递归地获得并更新Child Table,如果发现对应的表已经更新,忽略并进入下一步。对于DataRowState.Deleted,则是一种反向的方法进行操作。而最终的Data Access 又落在了UpdateIndependentTable(updatedRows)方法上面。

通过._useCommandBuilder 属性判断是通过使用CommandBuilder生成Command还是通过Mapped Stored Procedure来生成Command更新数据。

上面的是一个泛型的方法,我们可以对一个单独的Table的一个DataRow数组进行的更新,代码相对还算清晰,相信对大部分人没有难度:首先照例使用DatabaseProviderFactory创建泛型的DbCommandBuilder,指定SelectCommand的CommandText(Select * From TableName),通过DbCommandBuilder创建3个Command传递给DatabaseAdapter的3 个Command属性。如果用户开始了一个Transaction,则把创建的Transaction映射到3个Command上。最后调用DatabaseAdapter.Update方法实现 数据的跟新。通过DbCommandBuilder是一种很简单的方法,但是存在很大的性能问题。造成性能降低的主要原因有两个:他是使用纯文本的SQL;为了避免数据库的并发操作引起的数据不一致,它在作数据更新的时候,会逐个字段地把Dataset原始数据和数据库作比较。所以我们一边采用stored procedure来更新数据库。

通过stored procedure的方式和上面通过Command Builder的步骤差不多。首先通过Conection创建3个Command,并指定Command type为CommandType.StoredProcedure。通过storedProcedureNameMapping根据Table name获得对应的stored procedure的名称,并赋值给3个Command的CommandText属性。如果开始了Transaction,与之关联。通过DiscoverParameters方法(这个一个Abstract方法,需要在具体的Database 类脂Override)给Command发现参数。接着我们为3个Command的parameter指定SourceColumn和SourceVersion,其中SourceColumn通过我们配置的dbParameterNameMapping来获得。SourceVersion通过方法GetSourceVersion(这个一个Abstract方法,需要在具体的Database 类脂Override;这个方法根据参数名称来无额定对应的Source Version:Original or Current)来获取。最后调用DatabaseAdapter.Update方法实现 数据的跟新。

5. SQLDatabase & OracleDatabase

由于ADO.NET 2.0提供的很多基于泛型编程的功能,使得我们把觉得大部分Data Access操作放在了上面这个Abstract Database中,所以SQLDatabase & OracleDatabase上的逻辑很少。我们只看SQLDatabase。上面我们提到Abstract Database提供两个Abstract方法需要在具体的Database中实现的:DiscoverParameters和GetSourceVersion。实现上SQLDatabase之包含这两个方法:

作者:蒋金楠 
微信公众账号:大内老A
微博:www.weibo.com/artech
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
原文链接

开发自己的Data Access Application Block[下篇]相关推荐

  1. Enterprise Library v5.0 -- Data Access Application Block 开发向导(3)

    微软企业库 Enterprise Library 5.0 正式发布!!! Enterprise Library 5.0 开发向导- 简介(1) Enterprise Library v5.0 -- D ...

  2. EntLib 3.1学习笔记(2) : Data Access Application Block

    EntLib 3.1学习笔记(2) : Data Access Application Block 简化实现通用数据访问功能的开发任务.应用程序可以在很多情况下使用应用程序块,例如读取显示数据.获得通 ...

  3. [翻译]The Data Access Application Block

    Enterprise Library 4.1 - October 2008 The Data Access Application Block 数据访问应用块 The Enterprise Libra ...

  4. 感觉 Data Access Application Block(DAAB) 里也有可能写得不太好的地方

    昨天下载了博客园的代码,里面有一个 Data\SqlServer.cs 我不清楚是不是 MS DAAB 里的原样文件.不过前面有声明如下: // =========================== ...

  5. Enterprise Library: Data Access Application Block配置文件分析篇

    Enterprise Library: Data Access Application Block配置文件分析篇 Enterprise Library提供了Configuration Console配 ...

  6. Microsoft Enterprise Library 5.0 系列(五) Data Access Application Block

    企业库数据库访问模块通过抽象工厂模式,允许用户通过简单的配置选择不同的数据库作为程序的数据源,大大解决了切换数据库时带来的麻烦.因为我本机只安装了SQL Server 2005,所以在此只做SQL的演 ...

  7. 1,Composite UI Application Block (CAB) 介绍

    微软开发了一套开源的企业库 (Enterprise Library),通过使用这套企业库里面提供的各种应用程序块可以极大的提高应用程序的开发效率和缩短开发周期,也由此得到了大家的广泛应用. 企业库包括 ...

  8. Enterprise Library1.0 -- DataAccess Application Block

    Enterprise Library 对大家来说应该不陌生,很早我就听说了这个东西,但一直没有时间来学习,最近终于抽出时间来学习Enterprise Library,现在就把我学习过程中的一些实例发上 ...

  9. Composite UI Application Block (CAB) 详解

    微软开发了一套开源的企业库 (Enterprise Library),通过使用这套企业库里面提供的各种应用程序块可以极大的提高应用程序的开发效率和缩短开发周期,也由此得到了大家的广泛应用. 企业库包括 ...

最新文章

  1. BZOJ3559 : [Ctsc2014]图的分割
  2. php留言簿代码,php自治简单留言板代码
  3. Java Machine Learning Tools Libraries--转载
  4. JVM:常用调优命令
  5. UNITY 复制对象后局部坐标和世界坐标的变化问题
  6. 语言代码编程大赛简讯_精品干货:C语言的高效编程与代码优化
  7. html css div显示隐藏,Html-Css-div透明层剧中
  8. 贾跃亭“站台”!乐视高调宣布回归:60余款新品发布,还将发布超级手机
  9. php语言输出九九乘法表_PHP 输出九九乘法表
  10. 限时秒杀的整体代码在html中,限时秒杀.html
  11. python web开发框架 支持windows_基于Python的Web开发框架研究_曾浩
  12. go中分析工具:pprof
  13. 梦断代码----阅读笔记3
  14. 树型拓扑计算机网络的缺点是,计算机网络拓扑的优缺点 -电脑资料
  15. 简约至上设计书读后感
  16. Arduino + SmartAirFilter 制作智能感应的 PM 空气净化器
  17. 最漂亮的人是为梦想而努力的人
  18. sysvol 域控制器 文件_重建域控SYSVOL和NETLOGON共享
  19. 论文中不带边框表格制作方法
  20. python里的map是什么意思_python中map什么意思

热门文章

  1. 磁盘分区标为活动的方法及取消磁盘分区标为活动的方法
  2. Oracle Dataguard HA (主备,灾备)方案部署调试
  3. android点滴13:Eclipse连接不上模拟器(一片空白,无报错)
  4. python压缩与解压缩
  5. 安装neo1973的GPS驱动[转]
  6. IBM发布Open Liberty 18.0.0.4,支持MicroProfile 2.1和反应性扩展框架
  7. UWP 负载包含两个或多个具有相同目标的路径 'xxx'
  8. 拥抱 Node.js 8.0,N-API 入门极简例子
  9. Freemarker和Spring开发:获取相对路劲和绝对路径的最优方式
  10. [数分提高]2014-2015-2第6教学周第2次课(2015-04-09)