深入理解DataAdapter(一)
摘要
ADO.NET有两个核心组件:基于连接的Data Provider组件以及基于非连接的DataSet组件。基于连接的Data Provider组件常用于实时地从数据库中检索数据。而基于非连接的DataSet,似乎与数据库没有直接联系,仅仅用于在本地内存中存储Data Provider提供的数据表或集合。这一切似乎很微妙,此时,你是否在想:这两大组件是如何联系在一起的呢?或许,通过阅读本文会或多或少解除你的一些疑惑呢!
目录
1. 认识DataAdapter
前面我所讲的对象中,譬如Connection对象,Command对象以及DataReader对象,这些对象均属于Data Provider的一部分,而且都是基于连接的。拥有强大功能的它们,让你可以很轻松地连接一个特定的数据源,执行SQL语句,检索只读的数据流等等。这些基于连接的对象都对应于特定的数据源。换句话说,对于不同的数据源,我们需要找到对应的数据库提供程序(Data Provider)来匹配他们。当然,你也不必为此感到困惑和紧张,在前面我已经讲得很详细了。或许,以目前我们所学的知识,对于操作数据源以及检索数据完全没有什么问题呢!但是,这并没有发挥出ADO.NET的优势。如果,每次我们检索数据库中的表或者行都需要连接一次数据库,那么性能和效率是十分低下的。实际上,ADO.NET提供了基于非连接的核心组件:DataSet。DataSet组件让我们可以很愉快地在内存中操作以表为中心的数据集合,就好比操作数据库中的表一样。这是多么让人兴奋和激动啊!
不知道大家有没有想过这样一个问题(反正我是想了):既然DataSet是基于非连接的(不需要连接数据库),那么它存储的数据集合是从哪里来呢?实际上,很多时候,它的数据还是来自于数据库。Oh!这似乎有点自相矛盾了!打个“不雅”的比喻:就好比没有鸡,那哪来的蛋呢?你不妨换个角度来思考问题!虽然,你没有养鸡,但是,你不是还可以从超市或者其他零售店买到鸡蛋吗?同理,尽管DataSet没有直接连接数据库,但是,ADO.NET早就为DataSet准备了一位非常谦虚友善的中介:DataApdater。DataApater数据适配器,就是这样一个对象:它为外部数据源与本地DataSet集合架起了一座坚实的桥梁,将从外部数据源检索到的数据合理正确的调配到本地的DataSet集合中。
2. DataAdapter的工作原理
要说DataAdapter是ADO.NET世界里最为复杂的部分,其实也不为过!但是,我们也不必惊慌。尽管DataAdater内部实现机制较为复杂,但是提供开发人员的接口却是异常的简单。我们知道,DataApapter本质上就是一个数据调配器。当我们需要查询数据时,它从数据库检索数据,并填充要本地的DataSet或者DataTable中;当我需要更新数据库时,它将本地内存的数据路由到数据库,并执行更新命令。下面我们以Customer表为例,来理解DataAdapter的工作原理。下图详细描述了一个DataAdapter的工作过程。
图2.1 DataAdapter执行过程图
从上图我们可以清楚的知道,当我查询Customer信息,DataAdapter首先将构造一个SelectCommand实例(本质就一个Command对象),然后检查是否打开连接,如果没有打开连接则打开连接,紧接着调用DataReader接口检索数据,最后根据维护的映射关系,将检索到得数据库填充到本地的DataSet或者DataTable中。同理,我们需要更新数据源时,DataAdatper则将本地修改的数据,跟据映射关系,构造InsertCommand,UpdateCommnad,DeleteCommand对象,然后执行相应的命令。
之所以说,DataAdapter是最复杂的ADO.NET组件,是因为它是架构在所有其他DataProvider对象之上的。Connection对象,DataReader对象,Paramter对象以及Command对象,都尽可能的为它服务。总体来说,DataAdapter主要有三大功能:
- 数据检索:尽可能用最简单的方法填充数据源到本地DataSet或者DataTable中。细致的说,DataAdapter用一个DataReader实例来检索数据,因此你必须提供一个Select查询语句以及一个连接字符串。
- 数据更新:将本地修改的数据返回给外部的数据源相对来说稍微复杂一点。即使,从数据库查询数据时,我们仅仅只需要一条基本的Select语句,而更新数据库则需要区分Insert,Update,Delete语句。
- 表或列名映射:维护本地DataSet表名和列名与外部数据源表名与列名的映射关系。
3. 说说DataAdapter的重要成员
作为.NET DataProvider对象成员之一,DataAdapter跟其他数据提供对象具有相似的特征:都是基于连接的,都继承于基类,不同的数据源都对应自己的派生版本。这样理解的话,学习DataAdapter似乎简单的多。DataAdapter的基类是DBDataAdapter,它的结构如下:
public abstract class DbDataAdapter : DataAdapter, IDbDataAdapter, IDataAdapter, ICloneable
从上面我们可以看到,DBDataAdapter是一个抽象基类,不能被实例化,并且继承DataAdapter类,IDBDataApdater,IdataAdapter以及Icloneable接口。DataAdapter成员较多,必须掌握的有以下几种:
- SelectComand属性:获取或设置用于在数据源选择记录的命令。
- UpdateCommand属性:获取或这只用于更新数据源中的记录的命令。
- DeleteCommand属性:获取或设置用于从数据源中删除记录的命令。
- InsertCommand属性:获取或设置用于将新记录插入数据源中的命令。
- Fill方法:填充数据集。
- Update方法:更新数据源。
4. 总结
本文我主要从"WHY"与"WHAT"的角度详细讲解了DataAdapter的工作原理以及主要作用。后续的文章,我将围绕"HOW"来详细分析DataAdapter的实际应用。如果文章对园友们有帮助,希望能得到您的推荐和关注。您的肯定和支持是我继续写作的最大动力!