摘要:本文讨论如何以 ADO.NET 方式实现基本数据库操作,以及何时使用 ADO.NET 代替 ADO。
目录
.NET 中的数据访问
读取数据
DataSet、DataTable 和 Recordset
转换现有代码
更新数据
XML 扩展支持
总结
自若干年前推出开放式数据库连接 (ODBC) 应用程序编程接口 (API) 以来,出现了各种各样的数据库访问技术,而 ADO.NET 是其中最新的一种。在这过程中,发生了许多有趣的事。例如,COM 闯入数据库领域,开始培植 OLE DB 的殖民进程。然后,大致相当于 OLE DB 自动化版本的 ActiveX® Data Objects (ADO) 被选来统治 Windows® 数据库开发者的 Visual Basic® 和 ASP 社区。
通过 .NET,Microsoft 正在提供通用框架(即 Framework Class Library),其中将包括所有现有的 Windows API 甚至更多的内容。特别值得一提的是,它包括大量常用的库,而这些库现在需要通过各个 COM 对象分别获得。在这些库中,您会发现 XML 和 ADO 对象模型,它们被集成到了叫做 ADO.NET 的类子树中。
ADO.NET 事实上成为构建数据感知 .NET 应用程序的基础。和 ADO 不同的是,ADO.NET 遵循更通用的原则,不那么专门面向数据库。ADO.NET 集合了所有允许数据处理的类。这些类表示具有典型数据库功能(如索引、排序和视图)的数据容器对象。尽管 ADO.NET 是 .NET 数据库应用程序的权威解决方案,但从总体设计上来看,它不象 ADO 模型那样以数据库为中心,这是 ADO.NET 的一大特点。
ADO.NET 与 ADO 有很大差异。ADO.NET 是新的数据访问编程模型,需要开发人员的全面理解、投入和新思维。然而,一旦开始掌握 ADO.NET,您将意识到:原有的 ADO 技巧非常有助于您以不同、却更巧妙和可靠的方式来创建有效的应用程序和解决各种老问题。
在这篇文章的其余部分,我将集中介绍如何以 ADO.NET 方式实现基本的数据库操作。我想说明,在什么时候 ADO.NET 是比 ADO 更好的选择,而您最好在什么时候应放弃 ADO。ADO.NET 并不是将 ADO 改良以符合 .NET 基础结构而形成的。只要您看一下 ADO.NET 的语法、代码设计和移植,就会明白这一点。
.NET 中的数据访问
在 ADO.NET 中访问数据源的方式由托管提供程序确定。从功能上讲,托管提供程序与 OLE DB 的提供程序非常相似,但有两个重要的不同之处。首先,管理提供程序在 .NET 环境中工作,通过 DataReader 和 DataTable 等 .NET 类检索和公开数据。其次,因为它们的体系结构针对 .NET 进行了优化,所以比较简单。
目前 ADO.NET 提供了两种托管提供程序:一种用于 SQL Server™ 7.0 或更高版本,另一种用于其他所有您可能已经安装的 OLE DB 提供程序。在这两种情况下您分别使用不同的类,但遵循相似的命名规则。除前缀外,名称都是相同的。前一种情况前缀为 SQL,后一种情况则是 ADO。
您应该使用 SQL 类访问 SQL Server 表,因为它们直接进入数据库服务器的内部 API,跳过了由 OLE DB 提供程序表示的中间层。ADO 类是 OLE DB 提供程序上的 .NET 接口,它们使用 COM Interop 桥进行工作。
ADO.NET 对象的初学者可参阅 Omri Gazitt 的文章介绍 ADO+:用于 Microsoft .NET 框架的数据访问服务(英文)和我的 ADO+ 推动数据种类的演变(英文)一文。前者技术性较强,针对 ADO.NET 程序模型提供了高水平的评注性概述。后者主要介绍 ADO.NET 的目标和它与 XML、脚本以及其他技术之间的联系。
读取数据
需要从数据源中读取数据的 ADO.NET 应用程序首先要创建连接对象。根据目标提供程序的不同,该连接对象可以是 SQLConnection 或 ADOConnection。请记住,您可以使用 ADO.NET 类来连接到 SQL Server 数据库,但我们不建议这样做。其唯一的缺点是,您的代码要通过不必要的额外代码层。它先将 ADO 的托管提供程序调入,然后托管提供程序再调用 SQL Server OLE DB 提供程序。而 SQL Server 托管提供程序和 OLE DB 提供程序一样直接操作数据。
ADO 和 ADO.NET 连接对象之间的显著差异是:ADO.NET 连接不支持 CursorLocation 属性。请注意,这并不是一个文档错误,而是一个有争议的设计问题。为了突出以数据为中心的原则,ADO.NET 没有游标的显式实现。
在 ADO 中,您习惯了用游标从数据库或其他任何 OLE DB 兼容的数据源中抽取记录。您可以选择客户端或服务器游标,每种游标都有几个预先设定的游标类型。ADO.NET 则设计为从数据源中抽取数据,并提供新的编程接口来读取和分析数据。
在 ADO 中,您通过指定连接和命令文本来创建 Recordset 对象。对于游标的位置和类型,Recordset 有一定策略。您可以按下列方式之一读取数据:
在内存中创建选定记录的静态副本,然后在从数据源断开连接时根据需要处理这些记录。ADO 称之为静态游标。
通过快速、仅向前的只读游标来滚动数据,这种游标工作在记录的静态快照中。ADO 称之为只读游标。
通过服务器端的两种游标来访问数据,这些游标需要保持良好的连接,但您可以在各个不同层次上随时检测其他已连接的用户的更改。ADO 称它们为键集和动态游标。
前两种方式都在断开连接的记录集内工作,并从客户端缓存读取信息,这是它们的相似之处。另外,在面向 Web 的环境中和对于新的 n 层系统,这两种方式被证明是使用频率最高的。
在 ADO 中,以上所有这些方式与不同类型的游标相对应。您将在本文后面发现,虽然 ADO.NET 有很大不同,但它能实现您用 ADO 可实现的任何功能。只不过您的代码将从实际数据源及其物理存储媒介和格式中抽取数据。
ADO.NET 提供两个对象来处理从数据源中抽取的数据。它们是 DataSet 和 DataReader 对象。前者是记录在内存中的缓存,您可以从任何方向随意访问和修改。后者是高度优化的对象,专为以仅向前方式滚动只读记录而设计。请注意 DataSet 看起来象静态游标,但实际上,在 .NET 中与 ADO 只读游标相对应的是 DataReader 对象。
在 ADO.NET 中,不支持服务器端游标。然而,这不意味着您不能使用游标。您需要做的是在 .NET 中导入 ADO 类型库。在项目窗口的 References 节点上单击右键就行了。导入之后,您便可以开始在应用程序中使用本地 ADO 对象了。
尽管我承认下决心转向 .NET 是一件很难的事情,但我个人还是建议您考虑用 .NET 重写现有应用程序。可以把完全导入 ADO 作为迈向 .NET 的第一步,这无须投入太多的时间和资源。然而,请记住这只是漫漫长路上的第一步。这绝不是您迈向 .NET 的唯一一步。.NET 具有超值价值的的真正原因在于统一和一致的编程接口以及对本地类的广泛使用。您可以导入 COM 类型库,但导入 COM 类型库只能作为临时解决方案或者中间步骤,我们并不鼓励这样做。
使用 ADO.NET 时,应当充分考虑到它统一了数据容器类编程接口这一事实。无论您打算编写何种应用程序,Windows 窗体、Web 窗体还是 Web 服务,都可以通过同一组类来处理数据。不管在后端的数据源是 SQL Server 数据库、OLE DB、XML 文件还是一个数组,您都可以通过相同的方法和属性来滚动和处理它们的内容。
图 1:Solution Explorer 菜单
如果您坚持在 .NET 中使用 ADO,请准备面对一些副作用。例如,您需要额外的代码才能够从数据绑定控件中使用记录集。
DataSet、DataTable 和 Recordset
在 ADO.NET 中,没有与 Recordset 对象直接对应的对象。最接近的是 DataTable 对象。尽管这两个对象的