从 ADO 迁移到 ADO.NET(一)
原著:John Papa
翻译:sages
''''---Disconnecting an ADO Recordset oRs.CursorLocation = adUseClient oRs.CursorType = adOpenStatic oRs.LockType = adLockBatchOptimistic ''''— Or use adLockReadOnly oRS.OpenSet oRS.ActiveConnection = Nothing 起初 XML 功能并未集成在 ADO 中,随着 XML 的流行,在 ADO 后期版本中增加了对 XML 的支持。ADO Recordset 对象中的 Save 方法可以将记录集的行和列保存为一个预定义的 XML 大纲(schema),并将其保存为一个文件或流。使用 XML 大纲并不灵活,但是这是试图将一个 ADO 行集(rowset)保存为 XML 的第一次尝试,并且让开发者对未来的开发方向有个较清晰的认识。Recordset 也可以从一个 XML 文件中加载,前提是其使用同样的XML大纲。下列代码演示 ADO 如何将一个记录集保存为一个 XML 文件:
.Save "c:\MyRowSet.xml", adPersistXML 类似于 ASP 页面上的 Response 对象输出,行集可以保存为一个流。例如, 某些 ASP 代码可以接受一个请求,检索一个行集,将行集以流的形式发送给 Response 对象,后者将结果返给客户端。下列代码演示如何将一个记录集的内容保存为一个 Stream 对象。也可以将 Save 方法的第一个参数置为 Response 对象,这样就可以将 XML 行集流输出给浏览器:
Dim oStm As ADODB.StreamSet oStm = New ADODB.Stream oRs.Save oStm, adPersistXML
传统的 ADO 和 ASP 均支持流处理。当然,在.NET中,Web services 同样支持流,并且 Web Services 提供了比传统的 ADO 和 ASP 多得多的功能。实际上,Web Services 是一项处理数据请求并将数据以 XML 形式通过 HTTP 传输的技术。ADO 可以以流形式保存 XML,不过这是 ADO 后来的完善措施(afterthought)。而 ADO.NET 的 DataSet 对象通过 WriteXml 和 WriteXmlSchema 方法将其内容输出为一个 XML 文件或流。因此,ADO 的 Recordset 的 Save 方法是经过改进以适于将其内容输出为一个 XML,而 ADO.NET 的 DataSet 一开始就具有此特性。
ADO.NET 中不仅可以将 DataSet 保存为 XMl,并从 XML 加载 DataSet,并且它使用其类 XML 结构到别的用途中去。譬如,因为 DataSet 可以表示为 XML 形式,其可以很方便地在物理层和逻辑层间传递。这意味着,XML 可以在安全的网络上通过 HTTP 传送,同样 还可以以基于文本的 XML 形式传送。
由于构建在 XML 上,ADO.NET 可以工作在非连接状态。传统的 ADO Recordset 既可以工作在连接状态也工作在非连接状态, 取决于以下属性(譬如:CursorType = adOpenStatic 和CursorLocation = adUseClient),而在 ADO.NET 中,RowSet 对象分为连接态的(DataReader)和非连接态(DataSet)。
连接
创建连接的过程在 ADO 和 ADO.NET 中非常相似。首先,声明你的连接对象,初始化,设置其连接字符串,打开它。如 Figure 1 所示。第一个例子演示如何使用 ASP 和 ADO 来打开一个连接,第二个例子则在 ASP.NET 和 ADO.NET 做同样的工作。
ADO 和 ADO.NET 建立连接的主要区别在于 ADO 使用一个 Connection 对象来完成所有的与各种数据源的连接,而 ADO.NET 用不同的连接对象来表示与不同数据源的连接。例如,ADO.NET 含有一个System.Data.SqlClient 命名空间,其中包含所有 SQL Server 专用的 ADO.NET 对象(包括SqlConnection 对象)。SqlConnection 对象专门用于与 SQL Server 数据库进行通讯,因而是与 SQL Server 交互最快,功能最丰富的对象。还有一个更通用的命名空间 System.Data.OleDb,它可以与所有兼容 OLE DB 数据源通讯。因此,在 ADO.NET 中,可以创建多个数据提供程序命名空间(data provider namespaces)以连接特定的数据源,使数据访问速度更快,效率更高,允许每个命名空间充分利用目标数据提供程序 的功能。如果某个程序在运行时必须改变数据提供程序的类型,或者依赖一个数据提供程序而该数据提供程序不含有特定的 ADO.NET 连接对象时,该程序最好使用 OleDbConnection。
oCn.Open(); SqlCommand oCmd = new SqlCommand("SELECT * FROM Orders FOR XML AUTO",oCn); oCmd.CommandType = CommandType.Text; XmlReader oXR = oCmd.ExecuteXmlReader(); while(oXR.Read()) { Response.Write(oXR.ReadOuterXml()); }
该例子演示了 XML 如何被发送到调用浏览器。不过,XML也可以整个被聚集和流化到 Response 对象。''''-- ASP and ADO
Set oRs = Server.CreateObject("ADODB.Recordset")
oRs.ActiveConnection = oCn
oRs.Open "SELECT COUNT(*) As iRowCount FROM Orders"
iCount = oRs.Fields("iRowCount").Value 如果你只想取得仅仅一行和一列的信息,ADO.NET 中引入了从查询中获取单个值的新的方法。使用 ADO.NET 命令对象中的 ExecuteScalar 方法, 它可以返回其相关查询的第一行和列的信息。由于不必经过创建行集,查找该值,关闭行集等过程,因而开销非常之小。ExecuteScalar 方法在检索单值时是最佳的方法。下列代码和前例完成同样的任务, 但所使用的是 ASP.NET 和 ADO.NET 中 ExecuteScalar 方法:
string sSql = "SELECT COUNT(*) As iRowCount FROM Orders";
SqlCommand oCmd = new SqlCommand(sSql, oCn);
oCmd.CommandType = CommandType.Text;
int iCount = (int)oCmd.ExecuteScalar(); 另外一种获取单值的方法是使用存储过程的输出参数。该技术也需要检索大量的值。在 ADO 和 ADO.NET 中均可采用,不同的是 ADO.NET 扩充了输出参数的功能。为了在 ADO.NET 中从一个命令对象中得到输出参数的值,使用 ExecuteNonQuery 方法执行查询语句。该方法告诉 ADO.NET,该查询不返回行集,因而可以避免产生 DataSet 或 DataReader 的 开销:
oCmd.ExecuteNonQuery(); oCmd.UpdatedRowSource = UpdateRowSource.OutputParameters; int iOrderID = (int)oCmd.Parameters["@OrderID"].Value;
上述代码设置 UpdatedRowSource 属性以指向输出参数,前提是输出参数已被设置。然后就可以检索到输出的值。在传统的 ADO 中 ,Connection 对象的 Execute 方法使用一个模糊的参数来完成以上任务,而 ADO.NET 是以一种直白的方式来实现的。当然,在 ADO.NET 中还有一种最佳的方法来返回一个标准的行集——即命令对象的 Execute 方法。
传统的 ADO 的 Recordset 对象能运用 UPDATE、INSERT、DELETE 等语句,这些语句对于用 Recordset 变化后的值修改底层数据库来说是必须的。尽管该功能很方便,但也还是带来许多开销,因为它必须返回到数据库去了解如何进行该操作。
ADO.NET 中通过 CommandBuilder 对象做到这一点;虽然它同样带来系统开销。在大多数开发情况下,具体的 SELECT、INSERT、UPDATE、DELETE 操作在设计时间就可以确定下来。在传统的 ADO 中,没有 一种方便的方法将查询行为与 Recordset 关联起来以便 Recordset 可以利用这些它们的优势。而在 ADO.NET 中,一个 DataAdapter 有四个不同的命令对象与之相关联,分别代表每个查询 动作和 SELECT 语句。这使得 DataAdapter 可以使用一个查询结果去填充一个 DataSet,并告诉DataAdapter 事先在数据库上采取哪些 查询动作。当然在设计阶段这需要更多的代码,不过这些额外的代码对于性能的提高是值得的,更不用说代码的易维护性了,因为这些代码是自解释的。 在我五月份的“Data Point”专栏里详细讨论了 DataAdapter 的使用方法。
本文中我讨论了从 ADO 到 ADO.NET 一些关键特性的演变,包括 firehost 游标和持续化 XML。在后续专栏里,我将探讨更多有关游标的演变并示范如何处理并发问题以及在传统 ADO 和 ADO.NET 中如何进行批量更新。
发送问题和建议给 John 的邮件地址:[email protected]
本文地址:http://com.8s8s.com/it/it28562.htm