在Web跨入编程时代之前对于大多数IT管理者和顾问来说数据访问只是一个相对而言的问题所有要用到的数据都必须自己准备好人们主要关心的问题是选择性能/价格比最好的数据库服务器系统涉及的所有模块必须和服务器兼容客户机/服务器应用是这种两层模型最典型的范例
随着Web交互性的日益提高和应用的日益广泛对于第三层——中间层的需求也越来越突出中间层是一个逻辑层数据访问组件通常就在这一层上数据访问组件是唯一有必要了解数据库细节的代码同时准备更换或者升级数据库服务器时数据访问组件也是第一个需要修改的地方
接下来三层系统模型发展成了Windows DNA——现在称为Microsoft NET服务器系统Microsoft利用一个统一的模型进行数据访问这个模型注重的是内容而不是数据格式和存储媒介它的具体表达方式建立在UDA(Universal Data Access通用数据访问)的基础之上而UDA正是激励OLE DB体系发展的深层理念为了提供一种通过VB和ASP COM组件方便地无缝地访问OLE DB功能的途径Microsoft设计了ADOADO 是用来支持OLE DB的第一个版本在几年之内ADO发展到了版本增加和扩展了XML支持使得经过扩展的ADO对象模型能够匹配所有OLE DB改进功能(例如对于OLE DB新增的Row和Stream对象ADO 提供了类似的ADO配套功能)
一ADO 的核心功能超越了OLE DB
在多层系统中随着中间层组件的出现如何为表现层提供最新数据这一问题也随之出现表现层怎样访问数据?连接怎样打开?或者我们是否应该维护一份脱机记录(即一些断开连接之后仍旧能够在表现层使用的数据库记录)?ADO 以及它的更高版本同时提供了对服务器端游标和脱机记录集的支持(脱机记录集是一种COM对象它可以跨越网络串行化客户可以下载它然后脱机使用)
服务器端游标代表着一个紧密结合的保持连接的环境在这个环境中我们总是维持着各个层之间的有效通道只有结束时才拆除连接与此相反脱机记录集是一个有状态的对象我们可以把它作为一个整体处理且不必维持连接脱机记录集使用客户端的静态游标能够提供一个数据源的快照对于那些只有读取要求且需要在各个系统层之间移动数据的应用程序来说脱机记录集是很理想的今天大多数Web应用程序要求在各个层之间传输数据为了获取这些数据我们经常使用快速的只能向前游标用XML编码数据然后通过网络发送数据避免了在Web服务器上维持会话状态信息在分布式环境中数据库连接是一种关键性的资源以脱机方式工作保证了高可伸缩性
然而Web是一把双刃剑Web让我们连接到任何类型的联机服务而且能够与它们进行交互但是Web也要求一定程度的互操作性因为操作所涉及的各个服务可能运行在不同的软件和硬件平台上我们可以通过利用开放的标准以及那些不注重私有权的技术——甚至是象COM+这类广泛应用的私有技术跨越不同的平台
今天基于Windows的Web数据访问应用程序利用了ADO丰富的方便的编程接口然而ADO对象天生地定位在Windows平台上ADO基于COM的本性使得记录集很难在一个分布式异种平台构成的环境中使用另外即使目标平台可能允许我们使用ADO记录集它也不具备最有效的机制ADONET的DataSet和DataReader更有效而且如果没有ADONET有些时候我们还可以借助XML或纯文本获得高效率
为了在Web环境下传输数据Microsoft对ADO记录集进行了优化但COM类型转换仍旧是一个必不可少的步骤因为COM的数据类型不可能总是匹配ADO记录集的数据类型(例如String类型必须转换成BSTR类型)由此许多人把XML当成了粘合各个层的万能胶水——不管涉及到了哪些平台通常的做法是先提取一个记录集把它保存为XML格式然后传输结果数据流让接收者从这个XML数据流重新构造出记录集供以后使用随着对协同工作能力和可伸缩性要求的提高ADO不再是最理想的答案因为它不是建立在XML的基础上——但ADONET是
二ADO在Web环境中的不足
NET框架创立了一种取代COM和COM+的新组件模型NET的提出是Microsoft成熟的组件技术的新战略虽然几个关键性的COM特色不再在NET中出现但在某些方面NET与COM编程仍旧很相似因此COM程序员将能够方便地转向NET开发ADONET是Microsoft特别为NET框架设计的数据访问层它在很大程度上利用了NET的优势
为什么NET必须用一个新的数据访问层来替代现有的广泛应用的数据访问接口比如ADO?现代Web应用系统必须具备客户机/服务器应用和桌面应用的交互能力Microsoft设计NET的目标正是为了迎接设计现代Web应用系统的挑战同时NET也利用了各种Web协议广泛的强大的连接能力和协同操作能力
在非Windows平台上ADO记录集不能直接使用从而使得协同操作能力受到了限制为了突破这个限制我们要把记录集转换成XML格式然后传输转换得到的XML记录集在ADONET中把数据转换成XML以及通过网络传输的操作得到了简化和优化另外ADO对象模型中的每一个地方都体现了以数据库为中心的思想ADO把数据看成是一组来自数据源的记录而不是把数据看成一些独立的信息在ADO中如果脱离了数据提供者用来保存和描述数据的结构数据将不能独立存在
三ADONET数据集和ADO记录集
ADONET是从Web的角度对ADO进行检讨和改进Microsoft对ADONET的设计严格地体现了其名字的含义ADO再加上NETADONET自动连接网络致力于让Web数据访问变得更加简单和高效两个功能使得这方面的增强成为可能脱机记录集以及与生俱来的对XML的支持由于采用了脱机记录集方案ADONET自然也就不再支持服务器端游标ADONET天生就把记录数据保存为XML文档把模式(Schema)和数据视为分离的可替换的元素
如果你认为ADO早就提供了这些功能它们并没有什么创新意义那么ADONET还提供了其他许多新的功能ADONET能够使用连接的或者非连接的(脱机的)记录集具体由用户选择的游标类型和游标位置决定ADO记录集的本地存储格式是ADTG文件格式(Advanced Data TableGram高级数据表图)ADTG是一种Microsoft私有的二进制存储模式代表着记录集在内存中的映像XML是可替换使用的确定的详细输出格式在ADONET中我们可以断开一个记录集集合的连接通过一个默认(但允许更改)的XML模式再现记录集集合
在ADONET对象模型中DataSet(数据集)是最重要的对象一般地一个DataSet对象就是一个记录集的集合ADONET框架提供了记录集的所有数据库功能排序分页过滤视图关系索引和主键
DataSet对象代表了一个在内存中的有着丰富功能的数据缓沖区DataSet对象也通过表组织数据这些表与原始的数据源之间不存在连接我们可以添加表表可以通过读取本地或远程XML文件获得或者也可以从任何可访问的系统资源(包括内存和其他附属设备在内)读取我们可以排序索引过滤数据表象处理ADO的Recordset一样导航数据表
我们可以通过命令用数据集合填充DataSet对象如果用NET集合的形式为DataSet对象提供数据表(具有集合功能的NET数据类型是ICollection)同一个DataSet对象能够服务来自多个连接的多个请求ADONET的DataSet对象比ADO的Recordset更一般化与ADO的Recordset不同它是对数据源的一种抽象然而DataSet对象保留了一个在内存中工作的数据存储器它没有完全淘汰记录集功能如果我们只需要一次性地滚动记录集然后生成某种输出那么我们应该使用DataReader对象NET的DataReader对象类似于只能向前只读的记录集但它是一个高度专用化的对象所以无论在体积和开销上它都要比记录集小事实上记录集能够执行许多不同的任务是一个相当臃肿的对象与ADO的Recordset相比DataReader不包含进行家务管理的代码除了实现功能所必需的代码之外它不包含任何其他代码
把多个表作为一个整体管理以及允许建立这些表之间的关系这是ADONET的新功能我们可以用XML形式持久化或传输任何DataSet对象而且无需付出任何额外的代价因为DataSet对象本身就是按照XML格式构造因此除非要修改底层模式否则我们无需为了获得一个XML流而去转换DataSet对象的任意一个部分
四ADONET对象详解
ADO和ADONET有着两个截然不同的对象模型ADO定位在基于Windows 和NT的服务器平台ADONET定位在支持NET的平台Microsoft预期在年末推出第一个NET OS——Windows XP(原来的代码名字为Whistler)不过它的后继产品(代码名字为Blackcomb)更有可能提供一个全功能的NET OS
如果要迁移代码我们可以把现有的ADO代码导入到NET应用之中从而节省在编写代码方面的投入然而如果不做重大的设计调整同样的代码几乎不可能移植到ADONETADO和ADONET的对象模型不一样两者在不同的设计指导思想下完成
ADONET只用来构造基于NET服务器的Web应用ADONET是NET应用程序的数据访问API因此只有把服务器升级到NET之后你才可以考虑ADONET在同一个应用程序中让ADO和ADONET协同运作是没有什么意义的虽然你可以同时使用这两者(至少从设计的角度来看)但这并不是一种好的选择
ADONET的对象主要包括DataSetDataTableDataColumnDataRow和DataRelation这些对象的主要特点说明如下
▲ DataSet这个对象是一个集合对象它可以包含任意数量的数