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 ...
随机推荐
- LeetCode OJ:Convert Sorted Array to Binary Search Tree(将排序好的数组转换成二叉搜索树)
Given an array where elements are sorted in ascending order, convert it to a height balanced BST. 讲一 ...
- New Concept English three (50)
31 39 The New Year is a time for resolutions. Mentally, at least, most of us could compile formidabl ...
- 455. Assign Cookies Add to List
Assume you are an awesome parent and want to give your children some cookies. But, you should give e ...
- 批处理执行多个SQL文件到oracle
最近因为项目需要,打算写一个批处理程序,更新数据库中的表数据.写了3个sql文件:a.sql,b.sql,c.sql,在这三个文件中,实现了创建表,并向表中插入数据的操作.目前我通过SQLPLUS可以 ...
- jquery-post 异常
报错:Client closed connection before receiving entire response 前端请求: $.ajax({ type : 'POST' , url : '/ ...
- Django基础(五)
Django admin 自带的验证: from django.contrib.auth.decorators import login_required from django.contrib.au ...
- HTTP:HTTP清单
ylbtech-HTTP:HTTP清单 1.返回顶部 2.返回顶部 3.返回顶部 4.返回顶部 5.返回顶部 6.返回顶部 作者:ylbtech出处:http://ylbt ...
- socket关闭
首先应该了解win32 api closesocket,这里只说msdn文档中叙述不够清晰的地方. 首先说缺省情况:l_onoff为0,closesocket立刻返回,但底层依然在持续发包,并且试图优 ...
- 50 states of America
美国州名 州名英文 州名音标 简写 首府 首府 阿拉巴马州 Alabama [ˌæləˈbæmə] AL 蒙哥马利 Montgomery[mənt'gʌməri] 阿拉斯加州 Alaska [ ...
- Celery-4.1 用户指南: Canvas: Designing Work-flows(设计工作流程)
签名 2.0 版本新特性. 刚刚在calling 这一节中学习了使用 delay 方法调用任务,并且通常这就是你所需要的,但是有时候你可能想将一个任务调用的签名传递给另外一个进程或者作为另外一个函数的 ...