dazhong

导航

ADO.NET 2.0 功能一览

作者:Bob Beauchemin(DevelopMentor)
相关技术:ADO.NET 2.0、SQL Server 2005
难度:★★★☆☆
读者类型:.NET开发人员、数据库开发人员

    [导读]ADO.NET 2.0包含一个新的基类提供程序模型,适用于所有提供程序的功能以及对System.Data.SqlClient进行的更改。通过本文,您可以获得有关这些新功能的概述、它们的用法示例以及说明哪些功能不特定于提供程序和哪些功能特定于SqlClient的图表。

    ADO.NET 2.0随附了大量的新功能,这包括一个新的基于基类的提供程序模型、所有提供程序都可以利用的功能以及特定于System.Data.SqlClient的更改。因为.NET Framework 2.0是与SQL Server 2005一起发布的,所以其中的一些功能要求在SQL Server 2005种也可用。本文旨在充当新功能的概述和路线图,提供它们的用法示例,并且包含了一个说明哪些功能不特定于提供程序和哪些功能特定于SqlClient的图表。

基于基类的提供程序模型

    在ADO.NET 1.0和1.1中,提供程序编写器实现了一系列特定于提供程序的类。基于每个类都实现了一个通用接口的事实,所以,可以利用通用编码。例如,System.Data.SqlClient包含类SqlConnection,并且该类实现了IDbConnection。System.Data.OracleClient包含类OracleConnection,后者也实现了IDbConnection。特定于提供程序的类可以实现特定于数据源的属性和方法,例如,SqlConnection可以实现Database属性和ChangeDatabase方法。但OracleConnection不是这样,因为Oracle数据库不具有每个数据库实例拥有多个“数据库”(它们在ANSI SQL中称为编录)的概念。ADO.NET 2.0中的新提供程序模型基于System.Data.Common中的一系列基类。这些基类提供了常见功能的基本实现,当然,其中的每个基类还实现了仍然需要的通用接口,以便向后兼容。提供程序编写器可以选择使用基类或者支持接口。以前版本中的接口模型有两个特例:DataAdapter/DbDataAdapter和CommandBuilder。CommandBuilder类为一个简单的SELECT命令提供了对使用相同列集的INSERT、UPDATE和DELETE命令的自动实现。在保持CommandBuilder用于创建操作语句的基本算法的同时对其进行扩展是不可能的,因为SqlCommandBuilder是一个密封类。尽管仍然无法重用SqlCommandBuilder参数分析程序,但是System.Data.Common中有一个DbCommandBuilder基类。在这些类的基类级别也公开了新功能,DataAdapter/DbDataAdapter基类公开了用于将特定于提供程序的类型(如SQL Server SqlTypes)推到数据集(ReturnProviderSpecificTypes属性)中以及进行批更新(StatementType.Batch枚举值和UpdateBatchSize属性)的机制。DbCommandBuilder公共基类包含了一个用于指示并发策略选择的属性(ConflictDetection属性)。

提供程序工厂

    ADO.NET 1.0和1.1中基于接口的方法的复杂性之一在于:您无法在接口上调用构造函数,您必须创建特定类的具体实例。以前的API(如OLE DB和ADO)通过重载连接字符串来解决这一问题。连接字符串包含提供程序的COM PROGID,而正确的DataSource类是基于该PROGID创建的。因为OLE DB DataSource PROGID存储在注册表中,所以这是可能的。

' VB6 ADO code, Connection is an interface (actually it's _Connection)
Dim conn as Connection
' note that the default provider is MSDASQL, the OLE DB provider for ODBC
' this uses the OLE DB provider for SQL Server
conn.ConnectionString = "provider=sqloledb;.." ' other parameters deleted
conn.Open

    ADO.NET 2.0具有与此对应的解决方案。每个数据提供程序都在.NET machine.config中注册了一个ProviderFactory类和一个提供程序字符串。有一个ProviderFactory基类(DbProviderFactory)和一个System.Data.Common.ProviderFactories类,可以返回有关machine.config中注册的不同数据提供程序信息的DataTable,而且还可以在给定该DataTable中的提供程序字符串(称为ProviderInvariantName)或DataRow的情况下检索正确的ProviderFactory。以前通常按如下方式编写条件代码:

enum provider {sqlserver, oracle, oledb, odbc};

// determine provider from configuration
provider prov = GetProviderFromConfigFile();
IDbConnection conn = null;

switch (prov) {
    case provider.sqlserver:
        conn = new SqlConnection();
        break;
    case provider.oracle:
        conn = new OracleConnection();
        break;
    case provider.oledb:
        conn = new OleDbConnection();
        break;
    case provider.odbc:
        conn = new OdbcConnection();
        break;
    // add new providers as the application supports them
}

    现在可以按如下方式编写:

// get ProviderInvariantString from configuration
string provstring = GetProviderInvariantString();
DbProviderFactory fact = DbProviderFactories.GetFactory(provstring);
IDbConnection = fact.CreateConnection();

    由于出现了用于检索安装在计算机上的数据提供程序以及为每个数据提供程序检索ProviderFactory的标准,因此带来了其他一些有趣的可能性。

服务器枚举

    Machine.config中的提供程序配置项目指定了一个位掩码,以指示该提供程序支持哪些基类或基接口。这是因为并非所有的数据提供程序都需要支持System.Data.Common中的所有功能。例如,CommandBuilder是一个“最好具有”的类,但是没有它您也可以很好地完成工作。DbEnumerator是一个新的基类,它已经被添加到ADO.NET 2.0的混合功能中。该类使支持它的数据提供程序可以获得数据源列表。例如,SqlClient支持该类并且返回网络中可用的SQL Server实例的列表。这使得程序和工具可以为用户提供精选的数据源。使用这一功能的工具之一是Visual Studio 2005。

连接字符串生成器和元数据架构

    直到现在,Visual Studio .NET仍然使用OLE DB组件生成连接字符串以表示数据源。当您使用Visual Studio 2005中的服务器资源管理器在Visual Studio .NET 2003中添加新的数据连接时,它会显示OLE DB连接字符串生成器,该生成器会列出计算机上安装的OLE DB提供程序而不是.NET数据提供程序。然后,它允许您选择一个提供程序(虽然是OLE DB提供程序),并为相应的提供程序生成一个ADO.NET连接字符串。在Visual Studio 2005中,上面提到的DbProviderFactories可以为您显示一列.NET数据提供程序,并且图形用户界面组件使用类DbConnectionStringBuilder使程序员能够以图形方式生成连接字符串,以及从配置文件中加载连接字符串和在配置文件中存储连接字符串。Visual Studio 2005服务器资源管理器还可以获取数据源元数据(例如表、列、视图和存储过程的列表)以进行显示。ANSI SQL规范具有对应于该元数据的基本规范,该规范称为INFORMATION_SCHEMA视图。这些通用视图是一个很好的起点,但有时需要用特定于数据库的视图或信息进行扩展。在ADO.NET 2.0中,数据提供程序可以提供一个XML格式的配置文件,以列出哪些元数据可用以及如何从数据库中获得它们,这是因为并非所有的数据库都支持INFORMATION_SCHEMA视图。这将在允许工具程序员( tool programmer)获得提供程序定义的扩展信息集方面提供巨大的帮助。

跟踪

    允许程序员和技术支持人员在获得来自用户的说明或来自程序的错误信息之后,对数据库API的调用进行跟踪以查明问题位于数据访问堆栈中的哪个位置,将会非常有用。通常,问题可能产生于下列方面:

  1. 客户端程序和数据库实体之间架构不匹配。
  2. 数据库的不可用性或网络库问题。
  3. 不正确的SQL(无论是硬编码的还是由应用程序生成的)。
  4. 不正确的编程逻辑。

    在过去,编写代码以允许跟踪的工作是留给各个提供程序编写者完成的,尽管在某些API(例如ODBC)中存在一些事实上的标准。由于缺少标准的OLE DB跟踪,因此解决OLE DB和ADO问题变得更为困难。尽管这不是ADO.NET所独有的体系结构,但ADO.NET 2.0中的Microsoft提供程序利用了一般化的跟踪和检测API。使用这一新功能,您将能够在应用程序堆栈的任何级别跟踪问题。不仅Microsoft ADO.NET提供程序被检测,而且数据访问堆栈的其他部分也使用了该功能,并且提供程序编写者也可以实现该功能。甚至ADO.NET 2.0数据集和相关的类也具有内置的诊断机制。我将在以后的文章中深入讨论跟踪。

SqlClient增强

    Microsoft的主打数据库是SQL Server,而SqlClient是特定于SQL Server的提供程序。ADO.NET 2.0实际上随附了四个Microsoft提供程序:

  1. SqlClient—用于SQL Server的Microsoft提供程序。
  2. OracleClient—用于Oracle数据库的Microsoft提供程序。
  3. OleDb—用于在ADO.NET中使用OLE DB提供程序的桥梁提供程序。
  4. Odbc—用于在ADO.NET中使用ODBC驱动程序的桥梁提供程序。

    在ADO.NET 2.0中,已经对上述所有四个提供程序进行了增强,以便能够在部分受信任的环境中使用它们。通过正确地配置.NET代码访问安全性(CAS),可以启用更多以数据为中心的移动代码方案。在ADO.NET 1.1中,只有SqlClient提供程序支持该功能。此外,数据提供程序由数据库公司(Oracle的ODP.NET和IBM的用于DB2的数据提供程序)、提供程序专业公司(DataDirect Technologies)、开放源代码项目和个人编写。此外,Microsoft将在Host Integration Server 2004产品中随附DB2数据提供程序。因为SQL Server是软件难题的一个重要部分,所以除了对所有Microsoft支持的提供程序的增强以外,还有许多对ADO.NET 2.0中的SqlClient进行的增强。该功能的某些部分支持任何版本的SQL Server,而该新功能的大部分旨在支持SQL Server 2005(它的代号“Yukon”可能更容易为大家所知)中提供的许多新功能。SQL Server 2005支持在该服务器内部运行的.NET代码,而且在使用提供程序模型的服务器内部还有对数据访问的优化。一项较大的内部更改(并不显而易见)是,ADO.NET 2.0中的SqlClient数据提供程序不使用Microsoft数据访问组件(MDAC)。在该提供程序中还有更好的错误处理,网络错误的错误信息更加清楚,并且错误信息在总体上更加具体。以下是供程序员参阅的特定于SqlClient的功能概述。

连接池增强

    ADO.NET 1.0引入了一种用于汇集数据库连接的新基础结构。Microsoft SqlClient和OracleClient数据提供程序使用该基础结构,而OleDb和Odbc数据提供程序不使用该基础结构。新的池机制提供对连接池参数的粒度支持,包括最小和最大池大小以及池管理者等待将连接在池中变为可用的连接所需的用户自定义时间量的能力。ADO.NET添加了连接池增强功能,以使您能够以编程方式“排干”连接池;即关闭当前由汇集者保持活动的所有连接。您可以使用静态(在Visual Basic .NET中共享)方法SqlConnection.ClearPool清除特定的连接池,或者使用SqlConnection.ClearPools方法清除应用程序域中的所有连接池。SqlClient和OracleClient都实现了该功能。

异步命令

    有时,您希望在客户端或中间件代码中同时完成一件以上的工作,在本来就是多线程的中间件代码中,这是提高吞吐量的关键因素。在ADO.NET 2.0中,SqlClient目前支持异步命令执行。异步操作的.NET范型除了为同步操作提供一个方法以外,还能够为操作提供一组Begin和End方法。因为数据库命令的执行可能需要很长时间,所以SqlClient现在提供了内置的SqlCommand方法以便提供异步执行。下表列出了支持异步执行的方法和它们的同步对应方法。

同步方法 异步方法
ExecuteNonQuery BeginExecuteNonQuery
EndExecuteNonQuery
ExecuteReader BeginExecuteReader
EndExecuteReader
ExecuteXmlReader BeginExecuteXmlReader
EndExecuteXmlReader

    尽管异步执行可能是很好的功能,但不应当无故使用它,只有当您知道命令可能会运行很长时间并且您同时要完成某些有用的任务时才应该使用它。Windows NT系列操作系统中的Windows线程调度程序(该功能在Windows 9x和Me客户端上不可用)可花费它自己的开销以便在线程之间切换。同时请记住,某些.NET库是线程敏感型的;使用异步时,用于启动操作的线程未必是完成该操作的同一线程。但是,SQL Server网络库堆栈已经进行了增强,以便通过I/O完成端口来支持异步,并且这为异步SQL Server操作提供了更好的吞吐量。异步操作不但可以对多个操作语句和存储过程执行有效,而且在将其与SQL Server 2005中的多个活动结果集功能结合使用时,您还可以使用单个数据库连接多路复用异步SELECT语句。

批量导入

    很多数据库应用程序可以快速、大批量地将行“插入”到SQL Server中。这方面的典型示例是一个将行插入SQL Server的应用程序,这些行对应于从硬件设备(例如电话交换机或医院患者监视器)进行的读取操作。尽管SQL Server随附了实用工具(例如bcp)以适应这种情况,但这些实用工具通常使用文件作为它们的输入。SqlClient包含一个名为SqlBulkCopy的新类。该类的目的不是像BCP那样直接消耗来自文件的输入并产生文件输出,而是为了适应快速而有效地将很多行从客户端插入到数据库中这一情况。SqlBulkCopy可以从数据读取器和数据集获得它的输入。这意味着,您不仅可以直接从提供程序流式传输一系列行(DataReader),还可以用从硬件设备(不是提供程序)获得的外部数据填充数据集以及直接更新数据集;在这种情况下,不需要任何提供程序作为源。

// Fill up a DataSet
DataSet ds = new DataSet();
FillDataSetFromHardwareDevice(ds);

// Copy the Data to SqlServer
string connect_string = GetConnectStringFromConfigFile();
SqlBulkCopy bcp = new SqlBulkCopy(connect_string);
bcp.DestinationTableName = "hardware_readings";
bcp.WriteToServer(ds);

提供程序统计信息

    某些应用程序编写者发现在他们的应用程序中进行“实时”监视很有用。尽管您可以使用Windows性能监视器定义自己的性能类,以及使用内部的(并且可能会随着时间的推移而变得脆弱)SQL Server元数据调用来获得该信息,但SqlClient现在具有一种能够为您提供该信息的内置方式。通过SqlConnection类上的一个实例方法,您可以获得每个连接的统计信息(它们类似于ODBC API中提供的信息)。因为存储和收集这些统计信息需要花费自己的开销,所以有一个可以用来切换统计信息收集的属性。还有一个用于重置计数器的方法。当然,默认情况下会关闭统计信息收集;而且,当您通过在池方案中调用Dispose或Close将连接返回到连接池时会启动该功能。以下是产生的统计信息的示例:

string connect_string = GetConnectStringFromConfigFile();
SqlConnection conn = new SqlConnection(connect_string);
conn.Open();

// Enable
conn.StatisticsEnabled = true;

// do some operations
//
SqlCommand cmd = new SqlCommand("select * from authors", conn);
SqlDataReader rdr = cmd.ExecuteReader();

Hashtable stats = (Hashtable)conn.RetrieveStatistics();

// process stats
IDictionaryEnumerator e = stats.GetEnumerator();
while (e.MoveNext())
    Console.WriteLine("{0} : {1}", e.Key, e.Value);

conn.ResetStatistics();

Connection-specific statistics
BuffersReceived : 1
BuffersSent : 1
BytesReceived : 220
BytesSent : 72
ConnectionTime : 149
CursorFetchCount : 0
CursorFetchTime : 0
CursorOpens : 0
CursorUsed : 0
ExecutionTime : 138
IduCount : 0
IduRows : 0
NetworkServerTime : 79
PreparedExecs : 0
Prepares : 0
SelectCount : 0
SelectRows : 0
ServerRoundtrips : 1
SumResultSets : 0
Transactions : 0
UnpreparedExecs : 1

    有关这些统计信息所代表的确切含义的详细信息,请参阅ADO.NET 2.0或ODBC文档。

AttachDbFileName

    SqlClient数据提供程序支持桌面应用程序(其中,数据库存储在用户的桌面上)以及客户端-服务器应用程序和基于中间件的应用程序。有一种特殊版本的SQL Server,称为MSDE;该产品的SQL Server 2005时代的名称是SQL Server 2005 Express Edition。在桌面应用程序中,数据库本身就特定于应用程序并且与应用程序捆绑在一起。用户甚至可能不知道SQL Server正在被用作数据储备库,因为应用程序安装程序将运行SQL Server Express安装。为了便于将数据库文件附加到应用程序内部的SQL Server Express实例,ADO.NET 1.0提供了一个连接字符串参数—AttachDbFileName。但是,必须将该参数指定为硬编码的路径名,以便使用户难以在默认位置以外的其他位置安装该应用程序。在ADO.NET 2.0中,AttachDbFileName参数可以是一个相对路径,并且与应用程序配置设置一起使用。这使得为SQL Server Express设置桌面应用程序就像连接到基于Microsoft Access文件的数据存储一样容易。
SqlClient中特定于SQL Server 2005的功能

MARS

    当您使用SQL SELECT语句(作为独立语句或者在存储过程内部)选择一个行集时,SQL Server不会像某些数据库那样自动在该行集上产生游标。相反,它使用优化的方法在网络中流式传输结果集,并且有时会在网络库以数据包大小的块拉入数据时直接从数据库缓冲区中读取。这在SQL Server联机丛书中称为“SQL Sever的默认结果集”或“无游标结果集”。在SQL Server 2005之前的SQL Server版本中,在单个连接上一次只能有一个活动的无游标结果集。不同的数据库API和库将以不同的方式处理这个连接/无游标结果集行为。如果您试图打开第二个无游标结果集,则ADO.NET 1.0和1.1会产生错误;ADO“传统型”实际上会在幕后打开一个新的数据库连接。打开新的数据库连接更为方便,尽管它不如产生错误那样“精确”;这个方便的功能已经被某些程序员在无意中滥用,并且导致了比他们预料的更多的数据库连接。在SQL Server 2005中,数据库已经进行了增强,以允许多个无游标结果集同时在单个连接上处于活动状态。这就产生了功能缩写词“MARS”(多个活动结果集)。网络库进行了一些更改以支持该行为,并且新的网络库和新的数据库都需要启用MARS。

    在SqlClient代码中,您可以通过让多个SqlCommand实例使用同一个连接来多路复用结果集。每个SqlCommand都可以容纳一个通过调用Command.ExecuteReader产生的SqlDataReader,并且多个SqlDataReader可以串连使用。在ADO.NET 1.0和1.1中,您必须先关闭一个SqlDataReader才能获得另一个—即使使用了多个SqlCommand。请注意,您无法多路复用从同一SqlCommand实例的多个ExecuteReader调用中产生的SqlDataReader。下面是一个简短(但在功能上不是非常有用)的示例:

// connection strings should not be hardcoded
string connstr = GetConnStringFromConfigFile();
SqlConnection conn = new SqlConnection(connstr);
SqlCommand cmd1 = new SqlCommand(
    "select * from employees", conn)
SqlCommand cmd2 = new SqlCommand(
    "select * from jobs", conn)
SqlDataReader rdr1 = cmd1.ExecuteReader();

// next statement causes an error prior to SQL Server 2005
SqlDataReader rdr2 = cmd2.ExecuteReader();

// now you can reader from rdr1 and rdr2 at the same time.

    该功能不只是与减少错误有关,也不只是为了阐明曾经的ADO库魅力,它与上述的异步操作结合使用时,可能极为有用。多个异步SELECT语句或存储过程调用可以串连执行,从而节省了数据库连接并优化了吞吐量。请想像一下使用单个连接在窗体上同时填充20个下拉列表框。您还可以在结果集处于活动状态时执行无结果集返回语句。尽管同时可以有多个执行流处于活动状态,但所有执行流都必须共享同一个事务(如果事务存在的话)。事务仍然属于连接范围而不是命令范围。您可以通过像在以前版本的ADO.NET中那样设置SqlCommand Transaction属性来将SqlTransaction实例与SqlCommand相关联。

SqlDependency和SqlNotificationRequest

    在中间层缓存情况下,如果能够基于他人已经在数据库中更改某行的事实来刷新缓存则极为有帮助。程序员已经借助于一些不同的技术来实现该目标,例如,编写在表或视图更改时更新文件的触发器,或者无论数据库更改与否都经常刷新缓存。在SqlClient SqlNotificationRequest类和SqlDependency类出现之前,没有针对数据库通知进行注册的简单方式。SqlDependency是一个高级别类,它包装了SqlNotificationRequest并且将通知信息呈现为.NET事件。对于SqlNotificationRequest而言没有事件,您必须自己完成注册通知以及获得信息的“繁重工作”。绝大多数程序员都将使用SqlDependency。SqlDependency可以用作独立的类,并且在使用ASP.NET Cache类时可以直接使用它的功能。这一特定于SQL Server 2005的功能取决于SQL Server Service Broker—它是一项实现可伸缩队列系统的新功能。请注意,在使用ASP.NET Cache类时,应使用数据库轮询而不是Service Broker来获得类似的功能。在使用Service Broker和SQL Server 2005时,您不必为了获得通知而维护到数据库的连接。SqlDependency使用您选择的HTTP或TCP协议,并且在基础行更改时与您联系。该通知不包含任何特定于行的信息,当您获得通知时必须重新获取整个行集并重新注册该通知。该功能正是您对于单个缓存或有限的用户组所需要的,但是当您对同时侦听的大量用户使用它时,请务必小心。当任一行更改时,每个用户都必须刷新缓存中的整个行集。对于大量更改和大量用户而言,用于刷新的SELECT语句可能会对数据库产生重大影响。

密码更改

    SQL Server 2005提供了一种机制,以便使用与其他集成了登录的密码策略遵循同一过期机制的SQL登录(连接到SQL Server的Windows登录),该功能要求SQL Server 2005运行于Windows Server 2003上。如果SQL登录密码(例如“sa”)即将过期,则您将无法使用传统的Windows机制和密码更改API来更改它。您只能使用最终调用Transact SQL ALTER LOGIN的SQL Server客户端来更改该密码。SqlClient通过SqlConnection类上的ChangePassword方法适应这一机制。请注意,该方法只有在针对SQL Server 2005实例执行时才可用;尽管您可以在较旧版本的数据库上更改SQL登录,但该API使用的是其他SQL Server版本都不支持的网络数据包类型。密码更改的另一个需要考虑的方面是,在程序的连接字符串中不再对SQL Server登录ID和密码进行硬编码。除非您将生成.NET中间语言并在每次密码更改时都替换可执行文件(这不是一个可行的选择),否则必须在配置文件中存储您的SQL Server密码。严谨的SQL Server开发人员已经在相当长的一段时间内使用配置文件来存储(很可能是经过加密的)密码。更好的做法是始终使用SQL Server集成安全性(如果可能)。

System.Transactions集成

    ADO.NET 2.0中的SqlClient提供程序与新的System.Transactions命名空间相集成,从而启用了称为可升级事务的行为。尽管Transact SQL可以用来启动本地或分布式事务(BEGIN TRANSACTION和BEGIN DISTRIBUTED TRANSACTION),但在某些情况下(特别是在客户端/中间层编程方面),程序员可能希望编写可以在一个数据库方案或多个数据库方案中使用的组件。这些方案可能包含多个SQL Server实例,并且SQL Server可以自动检测到多实例访问并将事务从本地“提升”到多实例(分布式)。即使在使用多个数据库产品或多个连接的情况下,这也是可能的,前提是第一个数据库(在分布式事务术语中称为资源管理器)是SQL Server。在ADO.NET中,默认情况下启用可升级的事务。

客户端故障转移

    SQL Server 2005通过数据库镜像支持“热备用(hot spare)”功能。如果SQL Server实例失败,工作可以自动转移到备份服务器。这需要一个称为(并不意外)“目击实例”的实例来见证故障转移。热备用方案还要求现有的客户端连接必须“知道”故障转移(建立与新服务器实例的连接)。在下一次尝试访问时产生错误并且必须通过客户端编程手动进行“故障转移”的客户端连接是次最优的方案。ADO.NET 2.0中的SqlClient支持客户端故障转移,而不必对应用程序进行专门编程。

对新事务隔离级别的支持

    SQL Server 2005通过两个方法支持事务隔离:锁定和版本控制。以前版本的SQL Server支持锁定,但不支持版本控制。SQL Server 2005支持两种类型的版本控制,它们被称为语句级别版本控制和事务级别版本控制。该功能旨在有选择地减少极端环境中的锁定,并简化为版本控制数据库而设计的应用程序的转换。为版本控制数据库设计的应用程序在移植到锁定数据库时通常需要进行重大更改,反之亦然。版本控制数据库的默认行为几乎总是语句级别版本控制。有关差异的详细信息,请参阅Beauchemin、Berglund和Sullivan撰写的 A First Look at SQL Server 2005 for Developers(http://shopping.msn.com/search/detail.aspx?pcId=4644&prodId=2190289&ptnrid=141&ptnrdata=0)。

    不同的版本控制和锁定行为等同于使用特定的事务隔离级别启动事务。ANSI SQL规范定义了四个事务隔离级别:

  • READ UNCOMMITED.
  • READ COMMITTED.
  • REPEATABLE READ.
  • SERIALIZABLE.

    SQL Server支持所有四个隔离级别,甚至在SQL Server 2005之前就是如此。版本控制数据库通常仅支持READ COMMITTED和SERIALIZABLE。在版本控制数据库中,READ COMMITTED实现语句级别版本控制,而SERIALIZABLE实现事务级别版本控制。READ COMMITTED是几乎所有数据库的默认行为,无论是使用锁定还是使用版本控制。通过以数据库为单位设置数据库选项,可以启用语句级别版本控制,并且使其成为默认行为。在启用语句版本控制时,指定IsolationLevel.ReadCommitted或IsolationLevel.ReadUncommitted会使用该行为。为了支持事务级别隔离,SQL Server 2005定义了一个新的隔离级别—IsolationLevel.Snapshot,SqlClient(并且只有SqlClient)支持该隔离级别。该隔离级别是必需的,因为您可以分别启用语句级别或事务级别的版本控制,并且IsolationLevel.Serializable已经由SQL Server使用以便与锁定行为相对应。

数据类型——UDT、XML数据类型以及“MAX”BLOB和CLOB

    SQL Server 2005添加了对用户定义类型的支持,一个原生XML数据类型和更好的大型数据支持。它通过使用Transact SQL类型VARCHAR(MAX)、NVARCHAR(MAX)和VARBINARY(MAX)改进了大型数据支持。用户定义的类型和原生XML类型由SQL:1999和SQL:2003规范定义。为了将这些数据类型与SqlClient一起使用,定义了System.Data.SqlTypes命名空间中的新类(SqlUdt和SqlXml),将支持添加到SqlDbTypes枚举,并且增强了IDataReader.GetValue以支持将UDT作为.NET对象类型返回以及将XML作为.NET字符串返回。这些新的SQL Server 2005类型在SQL SELECT语句所返回的DataReader中受到支持,并且作为使用SqlParameter的参数。特殊的SqlMetaData类可以返回有关这些新数据类型的扩展属性的信息(例如某个强类型XML列所依附的XML架构集合)或某个UDT的数据库名称。您可以直接从客户端在通用代码中以及在数据集中使用这些类型。最后,您可以从客户端对“MAX”数据类型执行部分更新,这要求使用ADO.NET 2.0之前的特殊SQL函数。

小结

    唉呀!本文介绍了大量功能,很难用一两句话就讲清楚。为了避免您淹没在这个新的功能海洋中,我在本文最后提供了一个图表,其中列出了每个新功能以及使其正常工作所必需的数据库、提供程序和版本。目前,我只具有ADO.NET中包含的四个提供程序的信息,但其他提供程序供应商可能不久就会加入进来。

[附注] 新功能可用性

  所有提供程序 SQL Server 7/2000 SQL Server 2005
提供程序工厂 X X X
过部分信任运行 X X X
服务器枚举 X X X
连接字符串生成器 X X X
元数据架构 X X X
批更新支持 X X X
特定于提供程序的类型 X X X
冲突检测 X X X
跟踪支持 X X X
池增强 SqlClient和OracleClient X X
MARS     X
SqlNotificationRequest     X
SqlDependency     X
IsolationLevel.Snapshot     X
异步命令 X X X
客户端故障转移     X
批量导入 X X X
密码更改API     X
统计信息 X X X
新的数据类型     X
可升级的事务   X X
AttachDbFileName   X X

    作者介绍:Bob Beauchemin是DevelopMentor的讲师、课程作者和数据库课程联系人。他具有二十五年以上担任以数据为中心的分布式系统架构师、程序员和管理员的经验。他为Microsoft Systems Journal、SQL Server Magazine以及其他刊物撰写有关ADO.NET、OLE DB和SQL Server的文章,并且是 《A First Look at SQL Server 2005 for Developers》和 《Essential ADO.NET》的作者。

posted on 2007-04-09 12:16  大钟  阅读(282)  评论(0编辑  收藏  举报