ADO.NET的开发场景及传统ADO的处理2010-11-01 MSDN John Papa当转为使用ADO.NET时,您将需要了解如何应对以前知道用ADO处理而现在必须用ADO.NET解决的场景。就像使用Visual Basic、C++和ASP开发的N层解决方案经常要依赖ADO来满足数据访问需要一样,Windows?窗体、Web窗体和Web服务也要依赖ADO.NET。我曾经从使用传统ADO开发的角度讨论了如何使用ADO.NET来处理一些数据访问的场景。其中的一些主题包括将行集保留为XML、处理只进流水游标和执行Command对象的多种方式。在文中,我将继续讨论使用ADO.NET的开发场景,以及使用传统的ADO技术是如何处理的。我将从经常使用的传统ADO的只进、静态、键集和动态游标的情况开始讨论。我还要讨论如何处理并发性问题,以及断开连接的行集如何从ADO演变到ADO.NET。然后,我会说明如何将使用传统的ADO处理批量更新的代码转换为使用ADO.NET(用DataAdapter及其四个命令对象)的代码。分散Recordset的功能在ADO.NET中,ADO Recordset的大多数功能都分到了三个主要对象中:DataReader、DataSet和DataAdapter(参见图1)。

图1 ADO RecordsetADO.NET DataReader对象被设计成服务器端的只进、只读游标。ADO.NET DataSet对象是行集断开连接的存储工具。它存储记录,但不持有与数据源的连接,事实上,它并不关心其行集从哪个数据源派生。DataSet在内存中存储时是一个二进制对象,但是它可以轻松地从XML序列化和序列化为XML。这与ADO Recordset对象从其相关联的Connection对象断开连接(通过Recordset的ActiveConnection属性)时将CursorType设置为adOpenStatic、将CursorLocation设置为adUseClient是类似的。ADO.NET DataAdapter对象是连接与DataSet对象之间的桥梁,它可以通过一个连接从数据源加载一个DataSet,并用DataSet中存储的已更改的内容更新数据源。ADO Recordset的行为取决于其属性的设置(包括CursorType和CursorLocation属性)。在ADO.NET中构建了不同的对象来处理这些特定的情况,而无需用一个对象来应对所有情况。流水游标传统的ADO公开了四个不同类型的游标,可以改变ADO Recordset对象的运作方式。ADO Recordset对象的行为方式因其CursorType属性的设置情况互不相同,可能有非常大的差异。例如,通过将CursorType设置为adOpenForwardOnly,Recordset可保持与其数据源的连接,而且必须按只进方向进行遍历。然而,当您将CursorType属性设置为adOpenDynamic时,Recordset可向前或者向后遍历,甚至可以使游标跳到某个特定行。通过其CursorType和CursorLocation属性,ADO Recordset对象采用了一种将许多解决方案包装到单个对象中的方式。而ADO.NET采用的方法则不相同,它设计由不同的对象和方法来处理各种特定情况。在传统的ADO中,只进、只读游标是通过将CursorType设置为adOpenForwardOnly、将CursorLocation设置为adUseServer(这也是默认设置)实现的,这将使Recordset对象采用只进的服务器端游标形式。MoveNext方法将Recordset重定位到下一行,而MovePrevious方法则根本不允许使用,但是可以调用Recordset的MoveFirst方法。这有些容易引起误解,因为该方法并不将Recordset重定位到当前行集的开始;相反,它调用原来的SQL语句,从头开始重新填充Recordset,因此会再次移动到第一个记录。每次执行传统ADO Recordset的MoveFirst方法时(CursorType设置为adOpenForwardOnly),通过打开SQL事件探查器工具,观察SQL的执行情况,可以很容易地看到这一点。在需要逐个遍历成千上万(乃至更多)行中的每行或者在需要小一些的行集但是只需遍历一次(可能为了加载到一个选取列表)时,这种游标是非常常用的:
"-- Forward-only Firehose Cursor in ASP and ADO
Set oRs.ActiveConnection = oCn
oRs.LockType = adLockReadOnly
oRs.CursorType = adOpenForwardOnly
oRs.CursorLocation = adUseServer
oRs.Open sSQL
最接近这种传统的ADO流水游标的等效物是ADO.NET DataReader对象。和传统的只进ADO Recordset一样,DataReader在打开的同时保持着与其数据源的连接,而且只能以前进的方向进行遍历。但是,它们还是有区别的。区别之一是,专门为某个data provider(如SQL Server?(SqlDataReader类)或者ODBC数据源(OdbcDataReader类))编写单独的DataReader类型。ADO.NET DataReader对象非常高效,这是因为它是专门为实现只进、只读游标这一目的而构建的。传统ADO的只进游标是通过相同的Recordset对象(作为一个断开连接的Recordset甚至是一个数据源敏感的Recordset)实现的。而DataReader只是为了作为轻型流水游标而设计的。
//-- ASP.NET and ADO.NET in C#
SqlDataReader oDr = oCmd.ExecuteReader();