扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
作者:MSDN 来源:MSDN 2007年9月10日
关键字: ADO
适用于
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 直接或在后台获取结果集。这意味着,应用程序能够更快地获取数据并更好地控制这个过程。
在很大程度上,大多数应用程序中的数据访问逻辑都可以分为几个部分:
• |
获得连接:这涉及到构造连接字符串、(在某些情况下)集成用户提供的凭据,以及建立连接 — 实时或在操作周期内。 |
• |
管理查询:这意味着创建查询字符串和集成用户提供的参数,还包括管理事务。 |
• |
执行查询:这包括选择与返回的结果集相匹配的适当执行方法。有时是指使用可接收行集合、标量、流或只是执行操作命令的方法。 |
• |
管理(多个)结果集:这些例程存储和处理行集合、返回的参数,或将结果绑定到控件。在处理层次结构数据时,这些例程可能还会管理返回行集合之间的关系。在某些设计中,它们不但可以通过客户端或服务器端的游标进行定位,还可以排序、筛选或定位行。 |
• |
管理更改:当数据发生更改时,这些例程会将数据从静态源或绑定的控件移动到 ADO 数据结构中,以通过 ADO 数据结构管理更新、插入和删除操作。这些例程还管理并发冲突、批处理操作和事务。 |
• |
管理异常:所有这些例程都有异常处理程序,负责处理在建立连接、准备并执行查询或将数据分发到服务器时出现的常见问题。 |
ADO 开发人员将发现,他们能够以类似的方式分解和编写 ADO.NET 代码。但是,每部分都有差别,起初这有点令人沮丧,不过,只要单独处理就能够得心应手。Visual Basic 6.0 转换向导并不会将 ADOc 代码转化为 ADO.NET — 这是痴人说梦,因为 ADO.NET 采用的编程方法与 ADOc 不同。例如,如果使用 ADOc 中的 SHAPE 语法来管理层次结构,您会发现 .NET Framework 不支持 SHAPE,但是却支持通过 DataSet 类管理多个相关的行集合,一个 DataSet 类可以包含多个 DataTable 对象,每个 DataTable 对象包含一个独立的行集合。
每个 .NET 数据提供程序都负责实现符合自己“风格”的 ADO.NET 类。它们都支持一组使用(大致)相同的属性和设置的“核心”操作。当然,每个 .NET 数据提供程序还支持各自的 SQL 变体和 ConnectionString 设置。例如,SqlClient 提供程序(用于 Microsoft SQL Server)可实现 SqlConnection、SqlCommand、SqlDataAdapter 和 SqlDataReader,而 OleDb 提供程序还支持 OleDbConnection、OleDbCommand 等。在我撰写的书籍中,这些对象是根据功能来引用的 — 例如,SqlCommand 就称为“命令”类。
ADO.NET Connection (SqlConnection) 类与 ADOc Connection 对象类似,但是它接受一个不同(但熟悉)的 ConnectionString。它不能以异步方式开启,但是在执行 Fill 和 Update 方法时,它能够由 DataAdapter 自动管理。在 ADO.NET 中,不能直接针对 Connection 对象执行 SQL — 需要构建一条命令来完成这项操作。您还要修改连接错误处理程序,以使其预料到在尝试 ADOc 连接时发生的同一类问题。请注意,ADOc 使用的连接池机制与 ADO.NET 大致相同,但是通过 ADO.NET 管理池选项和状态更容易。
ADO.NET Command 类与 ADOc Command 对象类似,但是在这种情况下,必须构建一个 Command 对象来执行 SQL 或运行存储过程。ADO.NET Command 对象公开的方法与 ADOc 的方法有天壤之别。与 ADOc 不同,您可以访问一个新的低级接口 — DataReader (SqlDataReader),该接口公开一个高速原始数据流,用于返回查询数据。Command 类支持的 Parameters 集合与 ADOc 中使用的 Parameters 集合类似。请注意,ADO.NET 中的 SQL 参数标记方式有所不同。
您还会发现,ADO.NET DataTable 与 ADOc Recordset 大致等效。虽然它不是作为游标进行管理,但是通过它存储和管理返回的行集合更有效。定位到特定行与数组寻址一样容易。通过 DataSet,还可以一次管理来自不同数据源的多个行集合。这个类用于管理一个或多个 DataTable 对象以及这些对象包含的行集合。您能够编写这些行集合(即使它们来自分散的源)之间的关系代码,以及根据您定义的父子关系轻松地进行定位、筛选和搜索。
数据绑定也发生了变化。不用研究 Visual Basic 6.0 数据绑定的繁文缛节,只要在代码中使用拖放生成的代码或设置数据绑定链接,您就能够更轻松地绑定到行集合。ADO.NET 2.0 对数据绑定范例的精益求精使得这个过程更加简单。
对 ADOc Recordset 进行寻址的开销很大,因为所有列都是作为 Variant 返回的。ADO.NET 能够利用强类型的 DataTable 和 DataSet,因此进行对象寻址是小菜一碟。这意味着,数据以原始类型存储和管理 — 即,整数存储为整型,字符串存储为字符串。您可能还会注意到,强类型操作是更快的指令。我们还鼓励您在开发环境中使用“Option Strict On”和“Option Explicit On”选项。虽然这意味着代码必须显式强制变量(通过代码转换类型),但得到的代码将更稳定,以便在意外数据到达时不会像往常一样失败。
为了使管理表格更新更轻松,ADO.NET DataAdapter 模仿了 Visual Basic 6.0 数据对象向导 (DOW)。这个类允许定义自己的 UPDATE、INSERT 和 DELETE SQL — 一个特殊的 SQL 查询或存储过程。这使得 ADO.NET 更加轻巧,但是代码要承担生成这些命令的责任 — ADO.NET 不再像 ADOc 那样在运行时尝试生成这些命令。后面我们将看到,ADO.NET 2.0 重新引入了批文件更新和异步操作来提升性能。
与 ADOc 一样,异常处理也是 ADO.NET 设计的一个重要部分。幸运的是,.NET Framework 支持 Try/Catch 异常管理,与您熟悉的传统 Visual Basic 6.0“On Error”例程相比,它的功能更强大而且更灵活。这种异常管理方法允许您将那些以数据为中心的特定异常从其他问题导致的异常中筛选出来。这使编写异常处理程序更简单,并使应用程序意外失败的可能性更小。
ADO.NET 2.0 的最新版本填补了一些迁移 ADOc 时遗留的空白,并实现了一些闻所未闻的功能。这些创新允许您生成更安全、更健壮、速度更快的代码 — 特别是 Windows 窗体(客户端/服务器)应用程序。这些升级包括:
• |
没有 MDAC 依赖。ADO.NET 的早期版本通常要求升级 MDAC 堆栈(包括运行 ADOc 应用程序所需的 DLL),而 ADO.NET 2.0 在使用 SqlClient 时终止了这种依赖性。MDAC 的早期版本 (2.6-2.9) 能够满足 OleDb 和 Odbc .NET 数据提供程序。这意味着,安装 .NET 应用程序的破坏性较小,因为它不会影响现有的 ADOc 应用程序。 |
• |
异步操作。虽然 ADO.NET 2.0 不能像 ADOc 那样以异步方式打开连接,但是它能够异步地执行 DataReader 命令。这意味着,您能够编写代码,以便在执行查询期间为用户呈现一个进度条,或者在应用程序线程上执行其他工作,并根据进度返回状态事件。 |
• |
多活动结果集 (MARS)。在 ADO 2.0 之前,我们不能使用一个连接执行多个操作。但是 MARS 可以在同一个连接上支持多个操作。这意味着,在同时读取和更新行时,不必打开多个连接。当然,这要假定 .NET 数据提供程序和目标 DBMS 支持这个功能。 |
• |
批处理。ADOc 支持在一个往返行程中将多个操作命令发送到服务器的功能。这个功能在 ADO.NET 2.0 中重新实现了。通过批执行 Update 方法操作,应用程序的变更速度更快,并且与服务器之间的往返行程更少(更廉价)。 |
• |
BCP 支持。在将数据移出外部数据源或生成的数据源时,使用批量复制实用工具 (BCP) 代替传统的 ADO.NET 方法很重要。ADO.NET 2.0 现在包含一个 BCP 类,以允许直接访问这个高速的数据上载功能。在传统 ADO 方法所需的一部分时间内,这种方法就可以完成批量数据传输。 |
• |
将 DataSet 公开为 DataReader。为了使在层与层之间公开数据更方便,现在可以创建一个 DataSet(或 DataTable),并将该数据集作为 DataReader 传递到另一个层。您也可以直接从 DataReader 加载 DataTable。 |
• |
DataSet 序列化。在早期版本中,可以使用 Remoting 在各层之间传递 DataSet,但是数据是以 XML 格式传递的。在 ADO.NET 2.0 中,可以将 DataSet 序列化为二进制格式。这意味着层间性能的急剧增长,但是要使用 Microsoft 的专用格式来传输数据。另一个选项 (SchemaSerializationMode=TypedDataSet) 能够去除数据流中的架构,从而减少传输的数据量,同时仍然适用于跨平台的情况。 |
• |
Yukon 支持。ADO.NET 2.0 首次可以支持本地 SQL Server 2000 数据类型,还可能支持基于 CLR 的用户定义类型。这些数据类型包括 varchar(max)、nvarchar(max)、varbinary(max) 和新的 XML 类型。 |
• |
新的公共基类。为更轻松地编写通用应用程序,ADO.NET 2.0 公开了一个 DB* 基类。例如,公开 DbConnection、DbCommand 和 DbDataAdapter。这些类仍然要求使用特定于提供程序的 SQL 语法,但是通过它们可以编写出能够访问多个不同数据源的应用程序。 |
• |
服务器和提供程序枚举。这些新类允许您探索 .NET 数据提供程序提供的功能,以及应用程序可见的服务器和实例。在编写管理工具、启动/停止/暂停服务器或只是确定服务器状态时,这些类非常有用。请注意,除了 SQL-DMO,SQL Server 现在还公开了 SMO 来管理 SQL Server 实例。 |
• |
新的计数器。SqlClient 提供程序在 .NET 的早期版本中公开了许多计数器,但是它们都不太可靠。这些新的计数器将更精确,并且能够确定连接池机制的状态。 |
• |
连接池管理。ADO .NET 2.0 不但允许您清除一个或所有的池,而且还允许清除管理池行为的其他功能,而早期版本仅允许您选择连接池选项。改进的连接池机制还能帮助您检测坏池 — 连接到不可用服务器的池。 |
Whidbey 集成
ADO 集成到 Visual Basic 和 Visual Studio 已经有一段时间了。但是,Visual Studio 2005 团队这次在集成级别上进展地更加深入了一些。虽然不会看到创建熟悉的 DataAdapter 的向导,但是您将看到拖放技术,它们可以生成许多熟悉的和新的强类型数据结构。请记住,当您希望 RAD 接口生成代码时(特别是在简单的情况下),这些工具最有趣。Microsoft 声称他们还为支持 N 层开发做了大量工作。您可以创建在同一个程序集内生成 DataSet 的应用程序,也可以创建在引用的程序集中访问数据集以及自己的对象的应用程序。当设计变得较复杂时,这些工具可以公开您自己生成的中间层业务对象。有关该集成的讨论超出了本文的范围,但是在我的书籍中将涉及到这一点。
对于任何一种软件解决方案来说,都有一打替代解决方案 — 在完成一个解决方案后,总是有人能够就每一处指出一打替代方法。当然,每种方法都各有利弊。本文,我们将重点讨论数据访问接口的问题,并将其余的转换任务留给其他人。当然,您的数据访问代码或许没那么容易隔离。虽然迄今为止,大多数业界学者以及我本人已经谈论 3 层(或“N”层)设计几十年了,但并不是每个人都采纳我们的建议。如果您创建的应用程序带有一组处理数据的独立中间层对象,那么转换这些对象以支持 ADO.NET 的任务将非常简单。但是,如果您的代码零碎不堪,就像我多年以来审查的“意大利面条”代码,那么要将 ADOc 例程从应用程序的结构中清除而不使应用程序土崩瓦解,您可能会经历一段备受煎熬的过程 — 就好比在早春时节里,一边与俄罗斯狼犬格斗,一边试着拔掉它身上的狗毛。下面我们看一下替代方法 — 其中一定有一种方法对您和您的技巧有帮助。
• |
通过 Visual Basic 6.0 导入项目向导将您的项目转换为 ADO.NET 项目。据说新的 Visual Studio 2005 转换向导比以往的向导更加智能,但是它仍然不能将 ADOc 代码转换为 ADO.NET。虽然在较大且较为复杂的项目中应用它可能还需要一段时间,但是对于较简单的项目而言,实现转换应该是一帆风顺的。转换后,您将得到变换并包装在 COM interop 层中的 ADOc 代码,以便它能够在新的 Visual Basic .NET 项目中编译,并(与注册后的 MDAC 版本一起)部署和运行在目标系统上。这还意味着,您需要注意编码技巧(有一些晚期绑定技巧变形效果不太好),我在去年这个时候撰写的那篇文章中讨论过这些技巧。 |
• |
另一个可行的方法是访问每个 ADOc 代码区段,并按逻辑将其分解。想像一下,如果通过一个断开连接的 DataSet 就能完成任务,或者任务仅使用 DataReader 来返回行 — 这类似于默认的“消防栓”Recordset。在这种情况下,转换到 ADO.NET 是一种既简单又干净的过程。在处理服务器端游标(在客户端/服务器应用程序中特别常见)时,您需要决定重新设计代码以使用断开连接的 DataSet 的策略,或者考虑使用 ANSI CURSOR 操作符管理自己创建的服务器端游标类。在很多情况下,进行一些设计上的更改会消除对服务器端游标的需要。但是,这可能不符合实际情况,因此请三思而行。 |
• |
如果您在中间层组件中分离了 ADOc 代码,那么第三种方法将特别有用。在这种情况下,“只需”创建返回类似结构的组件的 ADO.NET 版本即可替换 ADOc 代码 — 假定组件使用者不将 ADOc Recordset 返回到其他层。如果您公开一个自定义业务对象类,则通过 Visual Studio 2005 中的工具将其变形为基于 ADO.NET 的数据访问组件将易如反掌。 |
主要考虑事项
在大刀阔斧地开展转换过程以前,您需要考虑着手点,并询问以下问题:“我能够克服所有艰难险阻来实现转换吗?”请考虑以下影响转换过程的因素:
• |
您从哪种类型的体系结构进行迁移?如果从 ASP 编程体系迁移,则 ASP.NET 方法将十分强大,并且管理 ADO 对象的方式也迥然不同。您会喜欢这种新方法,虽然在此之前它还不能处理双向数据绑定,但是现在可以了。 |
• |
您的技能如何?您最擅长哪种计算机语言?如果您编写过许多 Visual Basic 6.0 代码,并且像很多人一样使用 Visual Basic .NET 有一段时间了,那么“按逻辑”移植代码对您来说可能更容易。这就是变换操作,而不是代码本身。只要不使用服务器端游标,您就能够利用大多数连接字符串和 SQL。如果您的技能目前还没有达到这个水平,那么尝试从使用 Visual Studio 2005 迁移向导开始可能会更容易,这是因为大多数简单情况下进行的转换都不难。 |
• |
您的代码在多大程度上依赖于服务器端功能,例如,键集、动态游标或管理服务器端状态的例程(如 #temp 表)?在这种情况下,转换过程将更困难,因为即使是最新的 ADO.NET 2.0 也不直接支持该功能。但是,有一个替代办法 — 使用 ANSI CURSOR 命令。(请参阅我的文章使用 ANSI CURSOR 语句)。 |
• |
您是从 ADO 经典(ADOc 1.0 至 2.6 版)、DAO、ODBC 还是其他某个专用数据访问接口进行迁移?从比较新的 ADO 版本进行迁移要容易得多,因为很多概念是相似的 — 不是相同,而是相似。如果使用 Visual Basic 6.0 迁移向导,则无需改动即可移植大部分 ADOc 代码。当然,这会出现一些问题,我在以前的文章中提到过。 |
• |
但是,从 DAO、ODBC API 或专用接口进行迁移却是另一回事。自动化向导可能根本不能转换您的代码,甚至连尝试一下都不行。如果是这样,我建议您重新分析 DBMS 引擎。如果先使用 DAO,然后又使用 JET,我通常建议客户从 JET 迁移到 SQL Express,因为它更强大、更稳定并且具有更高的可扩展性。Microsoft 正在尽可能快速地全面替换 JET,我建议客户和学生也尽快替换。 |
• |
您使用的绑定控件是什么?尽管某些简单控件(如 TextBox、ListBox 和 ComboBox)的转换路径相当简单,但 DataGrid 却不是。Visual Basic .NET 中的绑定机制从根本上进行了改进并具有重大差异,因此在迁移复杂的绑定控件时,您可能会发现一些不连贯的地方。许多属性在 .NET 等效控件中不一样了,而且一些方法也没有了。第三方控件通常以 .NET 版本提供 — 您可能希望在冒险使用这些控件之前先调查一下。至于自定义控件,Visual Studio 2005 转换这些控件的效果更好,但是您不要期望过高 — 我怀疑这个转换向导的新增功能会出现很多问题。 |
• |
您准备编写自己的 SQL 操作命令逻辑吗?别忘了,ADO 经典在运行时会根据 SELECT 语句为您创建该 SQL。相反,ADO.NET 则鼓励您自己编写这些操作命令的代码。如前所述,您可以使用 CommandBuilder 并很快舍弃其局限性。我认为您将发现它不像 ADO 经典的 Update 方法那样灵活 — 特别是考虑到 Update Criteria 属性允许您更改所创建的操作命令的类型时更是如此。 |
是的,ADO“经典”代码可以变为 ADO.NET。实现过程像看起来那样难吗?我对此置疑。一旦理解 ADO.NET 是一个全新(且更好)的数据访问接口而不是 ADOc,您就会对转换过程更满意。并不是所有的应用程序都需要转换。我前面说过,如果零件没坏就不需要修理。我希望这对您有所帮助。如果您需要更多帮助,这里有几本书能够派上用场。无论如何,我希望本文能够助您一臂之力。
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者