日期:2009-03-13  浏览次数:20592 次

适用于

Microsoft ADO.NET

Microsoft SQL Server 2005(代号“Yukon”)

Microsoft Visual Studio 2005(代号“Whidbey”)

为什么需要进行迁移?

一个天气晴朗的下午,我在屋后的草坪上修好了三速自行车,父亲提醒我不应该修理没有损坏的零件。我举双手赞成。除非有迫不得已的原因需要修改功能性代码,并且在之前进行了合理的成本-收益分析,否则这样做毫无意义。用“合理”这个词的意思是,不以兜售情感的诱惑(这种诱惑可能来自于您的首席程序员,也可能来自于您配偶的亲戚)为转移、同时考虑到各种费用的全面分析,这些费用包括设计、开发、测试、部署和支持应用程序,以及对开发人员、支持团队和客户的重新培训的支出。为了运行该框架和新的应用程序,您可能还需要进行硬件升级,这笔费用也是要考虑的因素之一。众所周知,转换代码或者哪怕只是调整一下,开支也是很昂贵的。即使您小心翼翼,每一行更改的代码还是可能带来严重的后果和副作用(尽管通常是无意的)。尽管如此,还是存在转换现有代码的充足合理原因,例如:

也许现有代码无法利用硬件或 OS 方面的改进。例如,也许代码是设计为与(而且可能仅与)Windows 9x 一起工作,而客户已经升级到 Windows XP。

也许现有代码的竞争力不如其他公司编写的代码,后者的应用程序速度更快、更可靠,并且销售份额更大。这样的事情屡屡发生,因为客户总是力争在功能、特性、和有竞争力的价格方面保持领先。

也许新的应用程序伸缩性更好、能够支持更多的用户、更安全、更易于部署,或者轻松实现了现有技术所不具备的功能。

也许客户抱怨代码似乎工作一段时间后就会死机 — 特别是在安装了其他一些软件之后。

也许(可能最重要的是)您发现新的开发平台能够提高创建新应用程序,支持代码以及使用该平台的小规模用户的能力。

我不打算探究从现有代码基向新技术的诱人前景前进的决策过程。我将它留给您的 IT 人员。如果您阅读本文的目的是为了掌握转换基于 COM 的现有 ADO 代码(我称其为“ADO 经典”或 ADOc)的机制,以使其在 Visual Basic .NET 应用程序中运行,那么请继续。

我们是如何走到这一步的?

Microsoft 引入的数据访问接口历经了年复一年的更迭。起初,这些接口是为了访问特定版本的连接性引擎技术(Joint Engine Technology,JET)DBMS 和 SQL Server(通过 DB-Library)而专门设计的。随着这项技术的不断成熟,其他“继承”接口或通用型(one-size-fits-all,OSFA)接口(如 ODBC 和 OLE DB)生来就可以访问几乎所有的数据源。创建基于 COM 的 ADO(我称其为 ADOc)是为了方便访问 OLE DB。

ADO“经典的进演

时间流转,ADOc 不断发展并且其后来的 8 个版本也广泛应用,并集成到基于 COM 的 Visual Basic 中。ADOc 开发人员也学会了如何构建管理各种规模数据库的应用程序,并将其应用到世界各地的客户端/服务器、中间层和 ASP 体系架构中。ADOc 还支持存储过程(包括完整的 IO 参数管理)、自动的 UPDATE 查询生成、异步操作、客户端和服务器端游标、RO/FO 数据流等,因此为人们所普遍接受。但是,基于 COM 的 ADO 还存在一些问题。它对 MDAC 堆栈的依赖使其容易发生 DLL Hell 问题 — 有时,部署的应用程序在升级 MDAC 时会失败。

引入 ADO.NET

为了解决必须替换服务应用程序组件的问题,Microsoft 创造了 .NET Framework。除此之外,Microsoft 还创建了一个全新的数据访问接口 — ADO.NET。在创造 ADO.NET 过程初期,Microsoft 开发人员将新的数据访问接口称为“XDO”。这是由于这个新的数据访问范例是通过 XML 置入接口的,因此它能够读取 XML 文件以填充其对象,或者根据需要延伸 XML 以将数据和架构传递到其他层。因此,这个名字意义深刻。然而,Microsoft 认为如果创建另一个数据访问接口,开发人员将不知所措,甚至恼怒不休,所以将其命名为“ADO.NET”。当然,ADOc 和 ADO.NET 在更高层次上的功能相同。不过,这两者在后台的工作原理 迥然不同,而且依我看来,大部分都是很出色的。

ADO.NET 首次面世时,缺少很多现在看来成熟的 ADOc 所支持的基本功能。这些基本功能包括:批文件更新、异步操作、服务器端游标、运行时操作命令生成等。有些人认为,ADO.NET 是为了用于 ASP.NET 而设计的,客户端/服务器应用程序没有必要使用它,但是 Microsoft 坚信断开连接的 DataSet 能够使客户端/服务器应用程序更高效,并使其脱离对难以扩展的设计(这些设计依赖于服务器端状态管理)的依赖。正是由于该逻辑,ADO.NET 不包含对服务器端游标的支持。这个新思路的核心是“断开连接的”客户端数据存储,您可以根据需要轻松地将其保留并序列化为 XML,以便传递到其他层。它也非常适用于 Microsoft 的新 XML Web Services — 面向服务的体系结构 (SOA) 计划。注意,用于保留 ADOc Recordset 的 XML 与 ADO.NET 预期的 XML 格式不兼容。(请参阅 Much ADO About Data: Doing the Impossible (Again)。)Microsoft 还认为,最好允许开发人员构建自己的 SQL 操作命令(UPDATE、INSERT、DELETE)或通过向导构建,而不是依赖属性驱动的 ADOc Update 方法代码,因为在尝试搞清楚如何更改 Recordset 时,该代码经常出错。当然,在一些简单的情况下,这些代码也能够实现 CommandBuilder 以自动构建操作命令,但是正如本文所述,我认为您不会采取这种方法。(请参阅 Weaning Developers from the CommandBuilder。)的确,这些问题不是没有解决的方法,但是额外的开销会进一步阻碍人们进行迁移,或者使迁移过程难上加难。

解决疑难

另一方面,Microsoft 允许开发人员编写托管接口,直接解决了有关 OSFA 的问题。即 ADO.NET 公开了一个专用于 Microsoft SQL Server (SqlClient) 以及其他数据库(包括 Oracle 和 DB2)的 .NET 数据提供程序。这意味着,数据提供程序引擎能够利用 DBMS 的所有功能,并以最低的级别与数据库通讯。自 DBLibrary 以来,ADO.NET 第一次能够通过表格数据流 (TDS) — 它是低级协议,与 SQL Server 进行交互。这意味着,SqlClient 提供程序能够访问所有 SQL Server 功能,并了解这些功能之间的细微差别,从而使应用程序也就如虎添翼。对于开发人员而言,不存在将一种 DBMS 代码转换为另一种代码的问题,因为本地接口与 OleDb 和 Odbc .NET 数据提供程序实现的 .NET OSFA 接口类似。

ADO.NET 还公开 DBLibrary 的另一个功能 — 直接访问低级数据接口返回的数据流。这个接口在建立连接时以只进、一次一行的方式将您的代码链接到查询返回的输入数据,它作为 DataReader 实现。ADO.NET 中的所有方法都使用 DataReader 直接或在后台获取结果集。这意