General框架如何实现多数据库支持
关于用C#实现多数据库支持的方式,大家都会多少了解,本文从General框架的开发思路角度详细介绍General框架实现多数据库支持的方式,使更多的人了解General框架的底层实现并得到所需的相关知识。我在开发General框架之中,从网络中获取到了很多知识,对其他ORM框架亦有借鉴,其中借鉴最多的是NBear框架和NHibernate框架,我将从各处得到的开发思想融合进来,形成了我自己的开发方式。
简单说来,General框架支持多数据库的实现思路,无非是以下几点:
1、Ado.Net的多数据支持
2、SQL的多数据支持
3、数据管理器的多数据库支持
下面将具体进行说明。
1、Ado.Net的多数据支持
当我们初学C#的时候,会了解Ado.Net有五大对象,即Connection(连接对象)、Command(命令或执行对象)、DataReader(读取器对象)、DataAdapter(适配器对象)、DataSet(数据集对象),而我们开始常用的SqlHelper中,这五大对象是SqlConnection、SqlCommand、SqlDataReader、SqlDataAdapter、DataSet,后来可能会接触到支持多数据库版的SqlHelper,即DbHelper,这里面的五大对象会变为DbConnection、DbCommand、IDataReader、DbDataAdapter、DataSet,再后来我们发现其实SqlConnection、SqlCommand、SqlDataReader、SqlDataAdapter分别是DbConnection、DbCommand、IDataReader、DbDataAdapter的子类,即Ado.Net使用了抽象类来适应多数据库支持,所以编写支持多数据库的应用程序,只需要使用Db开头的Ado.Net对象就可以了。但是抽象类不能直接实例化怎么办,其实这里面还有一个工厂类用来创建抽象类的实例,即DbProviderFactory,但DbProviderFactory也是抽象类,仍然无法实例化,这时我们需要根据具体数据库类型,来使用不同数据库对应的Ado.Net的驱动中的DbProviderFactory的Instance就可以,各数据库对应的驱动类库和工厂类如下:
序号 |
数据库类型 |
对应的驱动类库 |
对应的工厂类 |
1 |
Access |
System.Data.OleDb(自带) |
OleDbFactory.Instance |
2 |
Sqlite |
System.Data.Sqlite(需下载) |
SQLiteFactory.Instance |
3 |
SqlServer |
System.Data.SqlClient(自带) |
SqlClientFactory.Instance |
4 |
Oracle |
System.Data.OracleClient(自带) |
OracleClientFactory.Instance |
5 |
MySql |
MySql.Data(需下载) |
MySqlClientFactory.Instance |
在General.Data中有一个BaseProvider,这个类是一个抽象类,负责提供数据库对应的工厂类的实例,每种数据库类型需实现自己的Provider并继承于BaseProvider,并提供实际的工厂类实例。还有一个DbCommon类,这个类负责跟Ado.Net打交道,使用的都是Db版的五大对象,它的构造函数参数即是BaseProvider,即需要用具体的Provider实现来创建DbCommon,而DbCommon就可以用具体的Provider实现所提供的工厂类实例来创建Db版的五大对象,这样也就可以使DbCommon可以适应不同类型的数据库。
2、SQL的多数据库支持
在Ado.Net层面实现多数据库支持之后,由于Ado.Net实际不涉及SQL的拼装,并且各数据库在SQL的实现上都会有多少的差异,比如SqlServer的参数前缀是“@”,而Oracle的是“:”,SqlServer用中括号括起来表示标记名称,而Oracle用双引号括起来表示标记名称,再如Sqlite没有“Top”关键字而有类似的“Limit”关键字等等,所以要实现支持多数据库的ORM框架,在生成Sql的时候需要根据不同的数据库类型来进行区别。
General.Data中有一个QueryBuilder类,这个类用来生成Sql语句,而这个类是抽象类,即每个数据库类型需要实现自己的QueryBuilder来区别不同的Sql语法,而通用部分的Sql,比如Select、Insert、Update、Delete等语句各数据库是一样的,所以不需要抽象而在抽象类中直接实现。QueryBuilder类不需要自身创建,而是通过BaseProvider的抽象方法GetQueryBuilder来由每个Provider的实现来创建,相应与QueryBuilder类似的SchemaManager也由BaseProvider的抽象方法GetSchemaManager来由每个Provider的实现来创建。这样,上层只要掌握Provider的创建,即可掌握对各数据库类型的支持。
3、数据管理器的多数据库支持
General.Data中DataManager类是所有数据库操作的接口,上一段说过:只要掌握Provider的创建,即可掌握对各数据库类型的支持。所以DataManager的初始化,其实就是Provider、DbCommon、QueryBuilder、SchemaManager的创建过程,而有了Provider,其余三者都可以由Provider来创建,而且只需要增加Provider和其对应的QueryBuilder、SchemaManager,就可以增加对更多数据库类型的支持。
为了方便配置,General.Data中添加了DatabaseType枚举类型,将已经实现的数据库类型支持包含在其中。配置时,只需要指定DatabaseType和ConnectionString,DataManager就可以自动创建对应的Provider等类的实例,也就完成了初始化。
在做多数据库支持时,还有一些意外的问题:
1、Sqlite数据库在读取数据时报“该字符串未被识别为有效的 DateTime ”异常
这是由于Sqlite不支持当前系统的日期时间格式,需要在保存数据时,将DateTime类型的值.ToString(“s”),为了解决这个问题,在General框架中加入了实体属性格式化方法,在实体属性映射上加上 Format = “s”,然后将 DataManager.Default.UsePropertyValueFormat = true,即可进行自动格式化。
2、Access数据库在保存数据库时报“xxx字段不能为空”
这是由于Access数据库表的文本字段未开启“允许空字符”,不愿开启这个选项的话可以设置DataManager. AccessConvertEmptyStringToNull = true,这样会自动将空字符转为DBNull值。
3、Oracle数据库在执行操作时报“xxx表或视图不存在”
这是由于建表Sql对表名加了双引号而Sql语句中表名大小写不正确,或建表Sql没有双引号Oracle自动将表名大写而Sql语句中表名不是大写,推荐建表Sql不要对表名加双引号并设置DataManager.OracleConvertQuoteNameToUpper = true。
General框架如何实现多数据库支持的更多相关文章
- 利用General框架进行三层架构开发
三层架构是企业信息管理系统中一种比较流行的架构方式,如大家所知,三层架构将信息系统分为数据访问层(DAL).业务逻辑层(BLL).界面表示层(UI)三部分,三层架构的好处是根据系统中代码所处的层次将系 ...
- 十三、EnterpriseFrameWork框架核心类库之数据库操作(多数据库事务处理)
本章介绍框架中封装的数据库操作的一些功能,在实现的过程中费了不少心思,针对不同数据库的操作(SQLServer.Oracle.DB2)这方面还是比较简单的,用工厂模式就能很好解决,反而是在多数据库同时 ...
- [Spring学习笔记 7 ] Spring中的数据库支持 RowMapper,JdbcDaoSupport 和 事务处理Transaction
1.Spring中的数据库支持 把具有相同功能的代码模板抽取到一个工具类中.2.关于jdbc template的应用 jdbcTemplate模板操作类,把访问jdbc的模板抽取到template中, ...
- 利用General框架开发RDLC报表
RDLC是微软推出的自家的报表软件,虽然没有一些第三方的报表软件强大好用,但是作为VisualStudio集成的报表工具,在客户要求不高的情况下还是非常值得一用的,本文将介绍通过General代码生成 ...
- tp框架where条件查询数据库
tp框架where条件查询数据库 Where 条件表达式格式为: $map['字段名'] = array('表达式', '操作条件'); 其中 $map 是一个普通的数组变量,可以根据自己需求而命名. ...
- SpringBoot 多数据库支持:
SpringBoot 多数据库支持: springboot2.0+mybatis多数据源集成 https://www.cnblogs.com/cdblogs/p/9275883.html Spring ...
- thinkphp 分布式数据库支持
ThinkPHP内置了分布式数据库的支持,包括主从式数据库的读写分离,但是分布式数据库必须是相同的数据库类型. 配置DB_DEPLOY_TYPE 为1 可以采用分布式数据库支持.如果采用分布式数据库, ...
- 在4.0框架下使用Sqlite数据库
在4.0框架下使用Sqlite数据库出现"混合模式程序集是针对"v2.0.50727"版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集. ...
- hisql ORM 框架研究(国内第一个支持HANA的ORM框架)
HiSql 操作说明文档 V1.0 下一代ORM框架 国内第一个支持HANA的ORM框架 hisql源码下载 git clone https://github.com/tansar/HiSql.git ...
随机推荐
- [转载] Java开发在线编辑Word同时实现全文检索
一.背景介绍 Word文档与日常办公密不可分,在实际应用中,当某一文档服务器中有很多Word文档,假如有成千上万个文档时,用户查找打开包含某些指定关键字的文档就变得很困难,一般情况下能想到的解决方案是 ...
- JS循环遍历JSON数据的方法
JSON数据如:{"options":"[{/"text/":/"王家湾/",/"value/":/" ...
- Django-form补充
Django_form补充 问题1: 注册页面输入为空,报错:keyError:找不到password def clean(self): print("---",self.cle ...
- [转]Angular移除不必要的$watch之性能优化
双向绑定是Angular的核心概念之一,它给我们带来了思维方式的转变:不再是DOM驱动,而是以Model为核心,在View中写上声明式标签.然后,Angular就会在后台默默的同步View的变化到Mo ...
- Ubuntu 16.04安装Elasticsearch,Logstash和Kibana(ELK)Filebeat
https://www.howtoing.com/how-to-install-elasticsearch-logstash-and-kibana-elk-stack-on-ubuntu-16-04 ...
- CEF源码编译
CEF的构造说明:https://bitbucket.org/chromiumembedded/cef/wiki/BranchesAndBuilding chromium的源码地址:https://c ...
- 在Linux上利用core dump和GDB调试segfault
时常会遇到段错误(segfault),调试非常费劲,除了单元测试和基本测试外,有些时候是在在线环境下,没有基本开发和测试工具,这就需要调试的技能.以前介绍过使用strace进行系统调试和追踪<l ...
- navicat链接远程数据库
1.之前使用的是常规的连接方式 学习源头: https://jingyan.baidu.com/article/0aa2237573c1e688cc0d6427.html 这里的ip地址是服务器的ip ...
- Linux评估 CPU使用情况
评价参数 1)CPU utilization:最直观最重要的就是CPU的使用率.如果长期超过80%,则表明CPU遇到了瓶颈:2)User time: 用户进程使用的CPU:该数值越高越好,表明越多的C ...
- EMC (电磁兼容性)
电磁兼容性EMC(Electro Magnetic Compatibility),是指设备或系统在其电磁环境中符合要求运行并不对其环境中的任何设备产生无法忍受的电磁干扰的能力.因此,EMC包括两个方面 ...