在我们开发很多项目中,数据访问都是必不可少的,有的需要访问Oracle、SQLServer、Mysql这些常规的数据库,也有可能访问SQLite、Access,或者一些我们可能不常用的PostgreSQL、IBM DB2、或者国产达梦数据库等等,这些数据库的共同特点是关系型数据库,基本上开发的模型都差不多,不过如果我们基于ADO.NET的基础上进行开发的话,那么各种数据库都有自己不同的数据库操作对象,微软企业库Enterprise Library是基于这些不同数据库的操作做的抽象模型,适合多数据库的支持项目。本文介绍基于微软企业库Enterprise Library 4.1的基础进行的多种数据库的处理。
1、企业库Enterprise Library版本的选择
在选择Enterprise Library版本的时候,我一直都是相对谨慎,因为我们开发的项目涉及很多不同的系统,有的需要XP的支持、有的需要Win7的支持或者Win10等等,需要考虑不同系统之家的兼容问题,由于微软企业库中的数据库访问模块相对比较稳定,因此也基本沿用使用稳定的版本,虽然目前Enterprise Library版本为6.0,但是之前一直在项目中使用的是3.1,这个版本可以在.NET 2.0的项目上运行,而且扩展类库也比较不错,因此一直保留着。
随着框架版本的升级,在XP上最高可以运行.NET 4.0的版本,因此可以考虑使用Enterprise Library 4.1或者5.0的版本(Enterprise Library 6.0版本需要.NET 4.5的支持,无法再XP上运行),相对来说,Enterprise Library4.1的扩展类库支持非常不错(http://entlibcontrib.codeplex.com/releases/view/38988),支持了SQLServer、DB2、MySql、ODP.NET(Oracle)、PostgreSQL、SQLite、SqlEx等数据库,而Enterprise Library 5.0版本扩展类库的支持还没有完整提供,需要自己处理。
因此综合上面的原因,我们为了照顾XP、Win7/Win8/Win10等不同系统的兼容性,可以从目前的Enterprise Library 3.1升级到Enterprise Library 4.1,这样可以利用较好的扩展类库的支持(支持支持了SQLServer、DB2、MySql、ODP.NET(Oracle)、PostgreSQL、SQLite、SqlEx等数据库),也相对提高下该数据访问模块的版本。
在我以前绘制的多数据库支持里面调整一下,把我们采用微软企业库后,支持的数据库作为数据层,示意图如下所示。
这样基本上常规的关系型数据库我们都支持了,我们需要开发任何数据库应用,都是统一数据模型,开发起来方便很多了,同时也方便在不同数据库管理系统中进行配置切换。
2、采用微软企业库进行架构设计
采用了微软企业库Enterprise Library作为我们底层的数据库访问模块后,对于多种数据库的访问操作,就会统一采用这个企业库的数据库访问对象,操作起来非常一致,为了对不同数据库的常规增删改查等一些操作进行进一步的封装,已达到简化代码的目的,因此我们可以为每个不同的数据库定义一个数据访问操作基类,以便实现一些不同数据库差异性的处理,但是它们还是有一个共同的数据访问基类。
采用不同的数据库,我们需要为不同数据库的访问层进行生成处理,如为SQLServer数据的表生成相关的数据访问层DALSQL,里面放置各个表对象的内容,不过由于采用了相关的继承类处理和基于数据库的代码生成,需要调整的代码很少。
针对数据访问层,我们需要设计好对应的继承关系,以便使得我们的基类能够封装大多数的操作,并给子类相对的弹性处理空间,如对于客户Customer的对象,数据接口层和数据访问实现层的关系如下所示。
这样整合多种数据库支持的底层后,整个数据访问的架构设计如下所示。
关于这个架构,我在前面很多文章都有阐述,如果我们还需要扩展一些特殊的数据库支持,可以参考随笔《基于Enterprise Library的Winform开发框架实现支持国产达梦数据库的扩展操作》进行一些扩展定制的操作。
3、基于Enterprise Library的多种数据库支持处理
前面我们提到,使用微软企业库Enterprise Library的好处就是可以统一编程模型,实现对多种数据库的兼容处理,而微软企业库Enterprise Library最大的特点是基于配置项实现多种数据库的处理,通过对使用不同的配置项,就可以迅速切换到对应的数据库上来,代码不需要修改。
对于一般的企业库配置处理,我们增加配置项如下所示。
<configSections> <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data"/> </configSections>
然后为不同的数据库添加不同的连接字符串
对于默认支持的SQLServer数据库,它的连接字符串如下所示。
<?xml version="1.0"?> <configuration> <configSections> <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data"/> </configSections> <connectionStrings> <!--SQLServer数据库的连接字符串--> <add name="sqlserver" providerName="System.Data.SqlClient" connectionString="Persist Security Info=False;Data Source=(local);Initial Catalog=WinFramework;Integrated Security=SSPI"/> </connectionStrings> <dataConfiguration defaultDatabase="sqlserver"> </dataConfiguration> </configuration>
不过对于一些扩展支持的数据库,我们还需要添加一些映射处理,如对于MySQL的支持,我们需要添加连接字符串:
<!--MySQL数据库的连接字符串--> <add name="mysql" providerName="MySql.Data.MySqlClient" connectionString="Server=localhost;Database=WinFramework;Uid=root;Pwd=123456;"/>
还需要添加ProviderMappings的支持,如下所示的XML。
<dataConfiguration defaultDatabase="mysql"> <providerMappings> <add databaseType="EntLibContrib.Data.MySql.MySqlDatabase, EntLibContrib.Data.MySql" name="MySql.Data.MySqlClient" /> </providerMappings> </dataConfiguration>
下面我列出所有不同数据库的连接字符串以及映射关系的一个完整版本,供参考。
前面我们提到了,基于配置实现不同数据库的统一处理,我们为了测试不同数据库的连接,我们可以使用下面的简单案例代码来获取数据进行展示。
其实现的代码如下所示。
我们看到,上面的代码没有针对具体的数据库,因此也是非常通用的处理,我们可以直接获取数据并展示出来,我上面案例在SQLServer、Oracle、PostgreSQL、MySQL、SQLite、Access、IBM DB2数据库均测试通过。
具体开发项目的时候,不同数据库有一些不同的处理,如分页操作、获取指定记录的处理等等,这些我们就需要发挥上面提到的数据库基类的功能了,通过基类功能的封装,我们可以除了可以使用所有数据库的共性外,还可以使用它的一些特定处理操作,这样我们就可以充分利用各种不同数据库的特点,但是又统一到一个开发模型上来,降低了各种不同数据库之间开发的成本,同时也减少不同数据库之间的迁移难度,提高代码的可阅读性和可扩展性。
上面关于数据库访问模块的框架构建,已经在我众多的Winform项目、Web开发项目,以及一些后台服务项目上运行良好,并使用了多年,为我们开发各种不同数据库,或者升级到不同数据库版本的处理工作上立下了汗马功劳。