.NET数据提供程序的构成
.NET数据提供程序的功能分为两类:非连接的数据支持、连接的数据支持。
下表列出了.NET数据提供程序的主要组件:
上表中组件的实现是基于一组接口定义的方法和属性,见下表:
提供程序工厂模型
从2.0版本开始,ADO.NET提供程序的架构得到了改进,引入了工厂类。每种.NET数据提供程序都包含继承于基类DbProviderFactory的工厂类。工厂类代码各自指定提供程序的公共入口,下表列出了工厂类的主要方法:
如果获取某种提供程序的工厂呢?我们可使用一个新引入的类DbProviderFactoryies,该类有几个静态方法。示例代码:
DbProviderFactory fact = DbProviderFactories.GetFactory( " System.Data.SqlClient " );
GetFactory方法接受一个字符串,该字串代表提供程序的恒定名称。这个名称被硬编码在注册每个提供程序的配置文件中。GetFactory会对所有已注册的提供程序进行枚举,返回与恒定名称匹配的程序集和类名信息。该方法会对工厂类进行反射,获取静态属性Instance的值(即使用单件模式获取工厂类的实例)。
DataProviderFactories的GetFactoryClasses方法能通过DataTable对象返回当前已安装的数据提供程序表。示例代码:
DataTable providers = DbProviderFactories.GetFactoryClasses();
SqlConnection类
该代表与SQL Server物理连接,位于System.Data.SqlClient命名空间中,实现了IDbConnection接口。
该类的属性见下表:
除ConnectionString外,其余属性都是只读的。
该类的方法见下表:
注意:连接即使超出作用范围也不会自动关闭。垃圾回收器无法识别对象的特殊功能,无法合理对其进行处理,因而连接也就不会被关闭。为此,必须在该对象使用完毕时显式调用Close或Dispose。
SqlConnection类提供了一个叫ChangePassword的静态方法,使开发者可以更改用户在连接字符串中指定的SQL Server密码。但要注意的是,该方法仅适用于SQL Server 2005以上版本。
在ADO.NET 2.0和更高版本中,所有托管提供程序都实现了GetSchema方法,用于获取数据库元数据信息(如:表、索引、视图、数据类型等)。
连接属性的配置
连接类的ConnectionString属性仅当连接处于关闭状态时才能设置。许多连接字符串的值在连接类中都有对应的只读属性。连接字符串中的属性名不区分大小写,如果出现多次,则采用最后出现的设置。
SQL Server连接字符串关键字见下表:
如果要执行涉及大型对象的大宗操作,那么提高数据包大小可能会有帮助,因为这样会减少读/写次数。
连接字符串生成器
使用连接字符串生成器(SqlConnectionStringBuilder类)可以在很大程度上降低注入攻击的危险,提高了安全性。
连接字符串的存储与获取
在.NET Framework 2.0和更高版本中,配置文件中定义了一个新区段,专门为存储连接字符串而设计,该区段为<connectionStrings>。
web.config文件中定义的所有连接字符串都会被加载到ConfigurationManager.ConnectionStrings集合中。
连接字符串的保护
我们可以使用系统工具aspnet_regiis.exe对连接字符串进行加密,示例:
aspnet_regiis –pe connectionStrings –app / core35
如果要将其解密,使用-pd代替命令行的-pe参数,示例:
aspnet_regiis –pd connectionStrings –app /core35
使用受保护区段内容的页面在运行于VS自带的本地Web服务器时不会出现任何问题,但如果相同的页面位于规范的IIS虚拟文件夹中,可能会出现RSA提供程序配置错误。为什么会这样呢?
基于RSA提供程序(默认的保护提供程序)需要“密钥容器”才能工作,默认密钥容器NetFrameWorkConfigurationKey在安装时被创建。该容器不仅要存在,还需与调用它的帐户相关联。假设在NetWork Service帐户下运行ASP.NET,我们需要以下命令为该用户添加访问权限:
aspnet_regiis –pa “NetFrameworkConfigurationKey” “NT AUTHORITY\NETWORK SERVICE”
必须指定完整的帐户名称。
注意:仅当使用RSA提供程序时才需授权密钥容器的访问权限。
连接池
连接池是高性能的,可伸缩的应用程序的基础。通过连接池,应用程序打开和关闭数据库连接的代价降低了。默认情况下,所有标准的.NET数据提供程序都会开启连接池功能。
连接字符串中的某些设置会直接影响池机制。下表列出了与连接池配置相关的连接字符串参数:
除Connection Reset外,上表中的所有关键字都适用于Oracle托管提供程序。
如果要关闭连接池,需将连接字符串中的Pooling参数设为false。
每个连接池都与一独有的连接字符串和事务上下文相关联。当新连接被打开时,如果连接字符串设置与现有池不匹配,则会创建新的池。一旦连接池被创建,在进程结束后才会被销毁。
当连接池被创建后,为达到池中最低连接数,会创建多个连接对象并将它们添加到池中。随后,按需添加连接,直到到达池连接数上限。当连接对象被请求时,只要池中有可用的连接,则从中获取。当前可用的连接必须是空闲的,事务上下文必须匹配或为空,且要拥有到服务器的有效连接。如果没有可用连接,连接池程序会创建新的连接对象。当到达池的连接数上限时,请求必须等待,直到有现有连接对象释放给连接池,排队的请求才会逐一被处理。
调用Close或Dispose方法后,连接便会释放。如果池中的连接数未达到上限,没有显式关闭的连接就不会返还给池,且该连接仍然有效。
如果连接对象有效期已过或发生严重错误,就会从池中被移除。这时,连接会被标记为无效,连接池程序会周期性地清理每个池,将无效对象永久地移除。
注意:为使连接工作更有效,在使用完毕后应试尽快将连接对象显式关闭返还给连接池。
Connection Lifetime关键字用于指示连接对象有效的期限,如果超出这段时间,连接对象应被释放。仅当处于集群中时,才能使用Connection Lifetime。
连接池的清理
如果某个异常指出连接池被破坏,ADO.NET会自动识别并找到那个连接池,将所有连接标记为过时,这样程序再申请连接时就必须创建新连接了。什么时候异常会指出连接池被破坏呢?那就是在之前打开的连接上从网络层引发的致命异常。
SqlConnection和OracleConnection有两个新的静态方法ClearPool和ClearAllPools可以编程方式在服务器停止或重启时清理连接池。ADO.NET在内部也会使用这两个方法清理连接池。