ADO to ADO.NET:未来之路
而言的问题;所有要用到的数据都必须自己准备好。人们主要关心的问题是选择性能/价
格比最好的数据库服务器,系统涉及的所有模块必须和服务器兼容。客户机/服务器应用
是这种两层模型最典型的范例。
随着Web交互性的日益提高和应用的日益广泛,对于第三层——中间层的需求也越来越突
出。中间层是一个逻辑层,数据访问组件通常就在这一层上。数据访问组件是唯一有必
要了解数据库细节的代码,同时,准备更换或者升级数据库服务器时,数据访问组件也
是第一个需要修改的地方。
接下来,三层系统模型发展成了Windows DNA——现在称为Microsoft .NET服务器系统。
Microsoft利用一个统一的模型进行数据访问。这个模型注重的是内容,而不是数据格式
和存储媒介。它的具体表达方式建立在UDA(Universal Data Access,通用数据访问)
的基础之上,而UDA正是激励OLE DB体系发展的深层理念。为了提供一种通过VB和ASP
COM组件方便地、无缝地访问OLE DB功能的途径,Microsoft设计了ADO。ADO 2.0是用来
支持OLE DB的第一个版本。在几年之内,ADO发展到了2.6版本,增加和扩展了XML支持,
使得经过扩展的ADO对象模型能够匹配所有OLE DB改进功能(例如,对于OLE DB新增的
Row和Stream对象,ADO 2.5提供了类似的ADO配套功能)。www.aspxuexi.com
ADO 2.0的核心功能超越了OLE DB。在多层系统中,随着中间层组件的出现,如何为表现
层提供最新数据这一问题也随之出现。表现层怎样访问数据?连接怎样打开?或者,我
们是否应该维护一份脱机记录(即,一些断开连接之后仍旧能够在表现层使用的数据库
记录)?ADO 2.0以及它的更高版本同时提供了对服务器端游标和脱机记录集的支持(脱
机记录集是一种COM对象,它可以跨越网络串行化,客户可以下载它然后脱机使用)。
服务器端游标代表着一个紧密结合的、保持连接的环境,在这个环境中我们总是维持着
各个层之间的有效通道,只有结束时才拆除连接。与此相反,脱机记录集是一个有状态
的对象,我们可以把它作为一个整体处理,且不必维持连接。脱机记录集使用客户端的
静态游标,能够提供一个数据源的快照。对于那些只有读取要求、且需要在各个系统层
之间移动数据的应用程序来说,脱机记录集是很理想的。今天,大多数Web应用程序要求
在各个层之间传输数据。为了获取这些数据,我们经常使用快速的“只能向前”游标,
用XML编码数据,然后通过网络发送数据,避免了在Web服务器上维持会话状态信息。在
分布式环境中,数据库连接是一种关键性的资源,以脱机方式工作保证了高可伸缩性。
然而,Web是一把双刃剑。Web让我们连接到任何类型的联机服务,而且能够与它们进行
交互。但是,Web也要求一定程度的互操作性,因为操作所涉及的各个服务可能运行在不
同的软件和硬件平台上。我们可以通过利用开放的标准,以及那些不注重私有权的技术
——甚至是象COM+这类广泛应用的私有技术,跨越不同的平台。
今天,基于Windows的Web数据访问应用程序利用了ADO丰富的、方便的编程接口。然而,
ADO对象天生地定位在Windows平台上。ADO基于COM的本性使得记录集很难在一个分布式
、异种平台构成的环境中使用。另外,即使目标平台可能允许我们使用ADO记录集,它也
不具备最有效的机制。ADO.NET的DataSet和DataReader更有效;而且,如果没有ADO.NET,
有些时候我们还可以借助XML或纯文本获得高效率。
为了在Web环境下传输数据,Microsoft对ADO记录集进行了优化。但COM类型转换仍旧是
一个必不可少的步骤,因为COM的数据类型不可能总是匹配ADO记录集的数据类型(例如
,String类型必须转换成BSTR类型)。由此,许多人把XML当成了粘合各个层的“万能胶
水”——不管涉及到了哪些平台。通常的做法是:先提取一个记录集,把它保存为XML格
式,然后传输结果数据流,让接收者从这个XML数据流重新构造出记录集供以后使用。随
着对协同工作能力和可伸缩性要求的提高,ADO不再是最理想的答案,因为它不是建立在
XML的基础上——但ADO.NET是。 www.aspxuexi.com
二、ADO在Web环境中的不足
.NET框架创立了一种取代COM和COM+的新组件模型。.NET的提出是Microsoft成熟的组件
技术的新战略。虽然几个关键性的COM特色不再在.NET中出现,但在某些方面,.NET与C
OM编程仍旧很相似。因此,COM程序员将能够方便地转向.NET开发。ADO.NET是Microsof
t特别为.NET框架设计的数据访问层,它在很大程度上利用了.NET的优势。
为什么.NET必须用一个新的数据访问层来替代现有的、广泛应用的数据访问接口,比如
ADO?现代Web应用系统必须具备客户机/服务器应用和桌面应用的交互能力,Microsoft
设计.NET的目标正是为了迎接设计现代Web应用系统的挑战。同时,.NET也利用了各种W
eb协议广泛的、强大的连接能力和协同操作能力。
在非Windows平台上,ADO记录集不能直接使用,从而使得协同操作能力受到了限制。为
了突破这个限制,我们要把记录集转换成XML格式,然后传输转换得到的XML记录集。在
ADO.NET中,把数据转换成XML以及通过网络传输的操作得到了简化和优化。另外,ADO对
象模型中的每一个地方都体现了以数据库为中心的思想。ADO把数据看成是一组来自数据
源的记录,而不是把数据看成一些独立的信息。在ADO中,如果脱离了数据提供者用来保
存和描述数据的结构,数据将不能独立存在。
三、ADO.NET数据集和ADO记录集
ADO.NET是从Web的角度对ADO进行检讨和改进。Microsoft对ADO.NET的设计严格地体现了
其名字的含义:ADO,再加上.NET。ADO.NET自动连接网络,致力于让Web数据访问变得更
加简单和高效。两个功能使得这方面的增强成为可能:脱机记录集,以及与生俱来的对
XML的支持。由于采用了脱机记录集方案,ADO.NET自然也就不再支持服务器端游标。AD
O.NET天生就把记录数据保存为XML文档,把模式(Schema)和数据视为分离的、可替换
的元素。
如果你认为ADO早就提供了这些功能,它们并没有什么创新意义,那么,ADO.NET还提供
了其他许多新的功能。ADO.NET能够使用连接的或者非连接的(脱机的)记录集,具体由
用户选择的游标类型和游标位置决定。ADO记录集的本地存储格式是ADTG文件格式(Adv
anced Data TableGram,高级数据表图)。ADTG是一种Microsoft私有的二进制存储模式
,代表着记录集在内存中的映像。XML是可替换使用的、确定的、详细输出格式。在ADO
.NET中,我们可以断开一个记录集集合的连接,通过一个默认(但允许更改)的XML模式
再现记录集集合。
在ADO.NET对象模型中,DataSet(数据集)是最重要的对象。一般地,一个DataSet对象
就是一个记录集的集合。ADO.NET框架提供了记录集的所有数据库功能:排序,分页,过
滤视图,关系,索引,和主键。
DataSet对象代表了一个在内存中的、有着丰富功能的数据缓冲区。DataSet对象也通过
表组织数据,这些表与原始的数据源之间不存在连接。我们可以添加表,表可以通过读
取本地或远程XML文件获得,或者也可以从任何可访问的系统资源(包括内存和其他附属
设备在内)读取。我们可以排序、索引、过滤数据表,象处理ADO的Recordset一样导航
数据表。
我们可以通过命令用数据集合填充DataSet对象。如果用.NET集合的形式为DataSet对象
提供数据表(具有集合功能的.NET数据类型是ICollection),同一个DataSet对象能够
服务来自多个连接的多个请求。ADO.NET的DataSet对象比ADO的Recordset更一般化;与
ADO的Recordset不同,它是对数据源的一种抽象。然而,DataSet对象保留了一个在内存
中工作的数据存储器;它没有完全淘汰记录集功能。如果我们只需要一次性地滚动记录
集,然后生成某种输出,那么,我们应该使用DataReader对象。.NET的DataReader对象
类似于“只能向前、只读”的记录集,但它是一个高度专用化的对象,所以无论在体积
和开销上它都要比记录集小。事实上,记录集能够执行许多不同的任务,是一个相当臃
肿的对象。与ADO的Recordset相比,DataReader不包含进行“家务管理”的代码,除了
实现功能所必需的代码之外,它不包含任何其他代码。
把多个表作为一个整体管理以及允许建立这些表之间的关系,这是ADO.NET的新功能。我
们可以用XML形式持久化或传输任何DataSet对象,而且无需付出任何额外的代价,因为
DataSet对象本身就是按照XML格式构造。因此,除非要修改底层模式,否则,我们无需
为了获得一个XML流而去转换DataSet对象的任意一个部分。
四、ADO.NET对象详解
ADO和ADO.NET有着两个截然不同的对象模型:ADO定位在基于Windows 2000和NT的服务器
平台;ADO.NET定位在支持.NET的平台。Microsoft预期在2001年末推出第一个.NET OS—
—Windows XP(原来的代码名字为Whistler)。不过,它的后继产品(代码名字为Blac
kcomb)更有可能提供一个全功能的.NET OS。
如果要迁移代码,我们可以把现有的ADO代码导入到.NET应用之中,从而节省在编写代码
方面的投入。然而,如果不做重大的设计调整,同样的代码几乎不可能移植到ADO.NET。
ADO和ADO.NET的对象模型不一样,两者在不同的设计指导思想下完成。
ADO.NET只用来构造基于.NET服务器的Web应用。ADO.NET是.NET应用程序的数据访问API。
因此,只有把服务器升级到.NET之后,你才可以考虑ADO.NET。在同一个应用程序中,
让ADO和ADO.NET协同运作是没有什么意义的。虽然你可以同时使用这两者(至少从设计
的角度来看),但这并不是一种好的选择。
ADO.NET的对象主要包括:DataSet,DataTable,DataColumn,DataRow,和DataRelati
on。这些对象的主要特点说明如下。
▲ DataSet:这个对象是一个集合对象,它可以包含任意数量的数据表,以及所有表的
约束、索引和关系。所有这些信息都以XML的形式存在,我们可以处理、遍历、搜索任意
或者全部的数据。图1显示了一个典型的DataSet对象的模式。在这个例子中,DataSet对
象包含两个表,其中一个表来自SQL Server,另一个表来自Oracle。两个表通过一个关
系连接到一起,关系把源表的一组记录和目的表的一组记录关联到一起(例如,主-细关
系)。另外,一个XML表通过一对一(1:1)的关系关联到了Oracle表。
▲ DataTable:这个对象代表着可以在DataSet对象内找到的所有表,如图2所示。我们
通过Tables属性访问DataTable的集合。类似地,通过DataSet的Relations属性可以访问
到所有已经建立的数据集关系。Xml属性包含了对象原始的XML描述,.NET应用程序可以
从这个XML字符串重新构造出数据集。
在ADO.NET对象模型的层次结构中,DataTable对象与ADO的Recordset对象最接近。根据
具体目的的不同,我们可以在数据集之内或之外创建和使用表。另外,我们可以手工执
行命令——但首先必须定义表的模式——或者,依靠受管理数据提供者创建和填充表。
(受管理提供者即Managed Provider,它是一种新的数据提供者类型,是ADO.NET中唯一
直接访问数据源的途径。这种提供者封装了一个数据源,通过Microsoft .NET类返回数
据。受管理提供者共用OLE DB的观念,但它是经过专用化的、优化的,而且很容易使用
。)
▲ DataColumn:表包含与列有关的信息,包括列的名称、类型和属性。我们可以按照下
面的方式创建DataColumn对象,指定数据类型,然后把列加入到表:
Dim dc As DataColumn
dc = New DataColumn()
dc.DataType = System.Type.GetType("System.String")
dc.ColumnName = "NameOfTheColumn"
任何时候,列的清单都可以通过DataTable的Columns集合得到。
▲ DataRow:要填充一个表,我们可以使用命令的自动数据绑定功能,或者也可以手工
添加行,方法是:创建DataRow对象,把DataRow对象插入到表,然后为该记录的各个字
段填写数据。我们可以通过Rows集合导航DataTable的元素,利用Rows集合实现一个顺序
导航器,或者,通过搜索或直接定位跳转到特定的记录。
▲ DataRelation:这个对象代表着两个表之间的父-子关系。关系建立在具有同样数据
类型的列上,但列不必有相同的精确度。关系可以是1:1、一对多(1:M)或多-对-多(
M:N)关系。关系可以方便地把对父记录的改动传播到子记录,但这不是默认行为。
要启用DataRelation对象,我们必须把一个ForeignKeyConstraint加入到待修改数据表
的ConstraintsCollection成员。DataTable对象的ConstraintsCollection成员决定了当
一个父表的值被删除或改动时,要执行一些什么动作。
设置了关系之后,ADO.NET将拒绝所有破坏该关系的数据集改动操作,并产生一个运行时
异常。在遍历表的记录时,调用GetChildRows方法可以从已连接的表访问所有相关的行
。GetChildRows方法返回一个DataRow对象的数组,这是一种新的分层式记录导航方式,
而传统的记录导航方式属于顺序模式或随机模式。
关系是不可传递的。假设表A关联到表B,表B又关联到表C的一些行。另外,假设在遍历
表A记录的时候,对于每一个表A的记录,我们要访问现有关系中的子记录。如果我们想
要访问对应表B中特定记录的表C记录,那么,我们不能使用由A-B的关系得到的表B的Da
taRow对象;相反,我们必须从表B打开一个新的表视图,找到我们想要的特定记录,然
后通过表B对表C的关系调用GetChildRows方法。
【Listing 1:创建和填充一个DataSet对象】
' 执行命令
Dim strConn, strCmd As String
strConn = "DATABASE=Northwind;SERVER=localhost;UID=sa;PWD=;"
strCmd = "SELECT * FROM Employees"
Dim oCMD As New SQLDataSetCommand(strCmd, strConn)
' 向数据集加入一个命名的表,得到一个静态快照
Dim oDS As New DataSet
oCMD.FillDataSet(oDS, "EmployeesList")
' 遍历各个记录
Dim oRow As DataRow
For Each oRow In oDS.Tables(0).Rows
Response.Write(oRow(0).ToString() + " ")
Response.Write(oRow(1).ToString() + "<BR>")
Next
Listing 1的代码显示了如何访问SQL Server标准的Northwind数据库,创建并填充一个
DataSet对象。关于DataSet及其下属对象的层次结构简图,请参考图2。
创建DataSet对象之后,我们打开了一个访问指定数据库的连接,并执行一个返回记录的
命令。这个命令可以是一个SQL命令,或者也可以是一个存储过程。下面的代码用到了F
illDataSet方法,FillDataSet方法允许我们把命令返回的表关联到指定的数据集。
Dim oDS As New DataSet
oCMD.FillDataSet(oDS, "EmployeesList")
数据集中的每一个表都有一个名字,我们通过这个名字来提取内容。ADO.NET真正的进步
源自数据集这一概念的提出,在ADO中不存在与ADO.NET DataSet类似的对象。虽然我们
无法从这个例子看出DataSet对象的重要性,但从体系结构上说,DataSet对象处于一个
不同的层次。它允许我们在同一个逻辑对象的组织之下管理多个表,这个功能为我们实
现主-细关系模式和数据绑定机制提供了前所未有的强大工具。另外,我们还可以通过索
引引用一个表。
五、修改数据
以脱机方式工作时,我们对数据的添加、修改、删除等更新操作在内存缓冲中进行。因
此,如果你利用NewRow添加了新的记录,或者利用某个简单的工具编辑现有的行,这些
更新只在内存中进行,不影响底层的数据源。更新操作在我们从Command对象调用Updat
e方法提交更改的时候发生。Update方法为数据集中每个被插入、修改、删除的行分别调
用Insert、Update和Delete命令。
我们可以利用ADO.NET命令的InsertCommand、UpdateCommand和DeleteCommand属性,指
定面向特定数据源的命令,插入、修改或删除记录。这些属性的内容和我们所要操作的
数据提供者有关,但是,如果数据提供者是一个数据库管理系统(DBMS),属性的内容
很可能就是SQL命令字符串。当Update方法执行时,如果这些属性还没有设置好,但Dat
aSet对象包含了主键信息,那么,ADO.NET将自动生成命令文本。
我建议,只有当应用程序要求读取一定数量的记录并进行修改,而且修改的次序和数量
不可预测时,才使用这种插入、更改、删除记录的方法。如果应用程序的用户界面只是
要求填写几个字段,然后插入或更新记录,那么,执行SQL语句或存储过程是更理想的方
法。
六、其他需要说明的问题
虽然ADO.NET不是一个特别庞大的主题,但本文仍旧只是粗略地勾勒了它的表面。如果不
理解隐藏在ADO.NET背后的深层原理,我们不能有效地利用ADO.NET。ADO.NET不仅仅是一
种新的数据访问API,更重要的是,当我们利用.NET的强大优势时,ADO.NET使得我们能
够跨越Web访问数据。如果你选择.NET作为服务器平台,你就应该用ADO.NET访问数据。
在.NET平台的设计过程中,Microsoft必须对如何进行数据访问做出决策。它可以直接移
植ADO,但ADO建立在COM的基础上,而且大多数时候它被用作一种OLE DB上的脚本接口,
一个紧密结合的、有连接的环境。Microsoft修改了ADO,淡化ADO以数据库为中心的色彩
,使得它更适合在一个宽松结合的环境中运行。在ADO.NET中,Microsoft实现了ADO与.
NET平台的一致性。不论我们编写的是Web表单、Windows窗体还是Web服务,如果系统中
存在一个数据源,ADO.NET总是提供一组相同的类。ADO.NET重新审视了Recordset对象,
把它的功能分割成了两个对象:DataSet和DataReader。如果你坚持使用ADO,那么,你
仍旧可以利用.NET导入ADO类,然而,ADO不包含任何ADO.NET不能提供的功能。
最后一个需要认识的重要问题涉及到Microsoft设计ADO.NET的方法。无论是在ASP.NET中
,还是在ADO.NET中,大多数改进体现了最优秀的开发实践经验。Microsoft简单地把各
种改动加入到一个一致的对象模型和一个“完全包容”的框架,单独的编程技巧在这里
变成了整体功能的有机组成部分。ADO.NET是数据访问的通用编程技巧和用户共同需求的
结晶,如果你要把Web系统升级到.NET,ADO.NET绝对是你必不可少的工具。 from:asp学习网/title:ADO to ADO.NET:未来之路/ time:2007-5-28 21:22:19
本文主题ADO.NET