ADO.NET概述
本节复习如何使用ADO.NET访问C#程序中的数据,主要介绍如何使用SqlConnection类和OleDbConnection类连接数据库,以及断开与数据库连接。深入讨论命令对象的各种选项,并说明如何为sql类和OleDB类的每个选项使用命令。如何使用命令对象来调用存储过程,这些存储过程的结果如何集成到缓存的客户端上的数据中。
介绍ADO.NET
ADO.NET比现在有的API在技术上高出很多。它与ADO仅仅是名称类型,类和访问数据的方法完成不同。
ADO(ActiveX Data Objects)是一个COM组件库,ADO主要包含Connection、Command、Recordset、Field对象。使用ADO时,要打开与数据库的连接,选择一些数据,并把它们放在记录集合中,这些记录集由字段组成,最后关闭联系。
ADO还引入:断开连接的记录集,当不适合使用连接打开相当长的时间时,就可以使用这个。
ADO.NET使用由ADO升级而来。并附带3个数据库客户端名称空间。
- 用于SQL Server
- 用于ODBC数据源
- 用于通用的OLE DB实现的数据库
如果数据库是不SQL Server,就应该在线搜索一个专门的.NET提供程序,找不到就应该使用OLE DB.
命名空间
下图显示了.NET数据访问中使用的类和接口命名空间。
共享类
ADO.NET包含许多类,无论是使用SQL Server类还是使用OLE DB类,都可以使用它们。命名空间是System.Data.
数据库专用类
除了共享类之外,ADO.NET还包含许多数据库专用类。这些类实现一组在System.Data命名空间对应的标准接口,根据需要允许类按照一般形式来使用。如SqlConnection类和OleDbConnection类都是派生与实现了IDbConnection接口的DbConnection类。
// 摘要:
// 表示 SQL Server 数据库的一个打开的连接。此类不能被继承。
[DefaultEvent("InfoMessage")]
public sealed class SqlConnection : DbConnection, ICloneable
// 摘要:
// 表示到数据源的连接是打开的。
[DefaultEvent("InfoMessage")]
public sealed class OleDbConnection : DbConnection, ICloneable, IDbConnection, IDisposable
其他专用类如下:
ADO.NET类最重要的功能是:它是以断开连接的方式工作。特别适合Web为中心环境。传统的ADO2.1引入断开连接的记录集,但是由于不是一开始就设计好,不如ADO.NET完善。
使用数据库连接
为了访问数据库,需要提供某种连接参数,如运行数据库的计算机和登录证书。ADO.NET连接类是OleDbConnection和SqlConnection。类的层次结构如下
代码示例
using System.Data.SqlClient;
string strConn = "Data Source=****;Initial Catalog=***;User Id=sa;Password=****;";
SqlConnection conn = new SqlConnection();
conn.ConnectionString = strConn;
conn.Open();
//做一些事情
conn.Close();
管理连接字符串
在以前的版本中,由开发人员管理数据库连接字符串,其方法是把连接字符串存储在应用程序配置文件中,或者直接硬编码连接字符串。
.NET2.0开始,有一种预定义的方式存储连接字符串,要定义数据库连接字符串,应该使用配置文件中
<connectionStrings>
<add name="ADOTest" providerName="System.Data.SqlClient"
connectionString="Data Source=***;Initial Catalog=***;User Id=sa;Password=**;" />
</connectionStrings>
程序中读取数据库连接的方法示例:
private static DbConnection GetDatabaseConnenction(string name)
{
ConnectionStringSettings settings = ConfigurationManager.ConnectionStrings[name];
DbProviderFactory factory = DbProviderFactories.GetFactory(settings.ProviderName);
DbConnection conn = factory.CreateConnection();
conn.ConnectionString = settings.ConnectionString;
return conn;
}
这对应获取数据库连接似乎是不必要的工作,如果应用程序从来不运行在其他数据库上,这些工作的确没有必要,但是使用签名的工厂方法和泛型Db*类,就会发现以后将应用迁移到另一个数据库系统上非常简单方便。
高效地使用连接
一般情况下,当在使用“稀缺”的资源是,如数据库连接、窗口,最好确保每个资源使用完成立刻关闭,尽管有自动垃圾回收,但还是尽早释放资源,避免出现资源的匮乏的情况。下面介绍两种方式确保数据库连接等类似“稀缺”资源在使用后立即释放。
- 第一种方式----利用try...catch...finally,确保在finally块中关闭任何打开的连接。
- 第二种方式---使用using语句块
在using语句块中无论块是如何退出的,using子句都会确保关闭连接。在编程时,应至少使用两种方法中的一种,或者两种方法都使用,最好是组合使用这个两种方法。
事务
对数据库要进行多次更新,这些更新必须在事务的范围内进行。我们常常要在代码中查找一个事务对象,它传递给许多方法,以便更新数据库。
2.0以后在System.Transacions程序集中添加了TransactionScope类,简化了事务代码的编写,可以把几个事务方法合并到一个事务范围中。
在事务作用域中,可以选择在该事务中执行命令的独立级别,该级别确定了如何在一个数据库会话中查看在另一个数据会话中所进行的修改,并不是所有数据库都支持。
这个节比较难懂,一般不会这样使用事务的,会使用数据库事务。
命令
命令就是一个要在数据库上执行包含SQL语句的问题吧字符串,也可以是一个存储过程。
把SQL子句作为一个参数传递给Command类的构造函数,就可以构造一条命令。
<provider>Command
类有一个CommandType属性,它用来定义某条命令是SQL子句、存储过程还是完整的表语句。
执行命令
定义好命令后,就需要执行它,执行语句有许多方式,这取决于要从命令中返回什么数据。
<provider>Command
类提供了如下执行命令:
- ExecuteNonQuery()--执行命令,但返回影响的行数。
- ExecuteReader()--执行命令,返回一个类型化的IDataReader
- ExecuteScalar()--执行命令,返回结果集中的第一行第一列的值。
sqlCommand类提供了下面方法:
- ExecuteXmlReader()---执行命令,返回一个XmlReader对象,它可以遍历从数据库返回的xml片段。
ExecuteNonQuery()方法
这个方法一般用于update、insert、delete语句,其中唯一的返回值是受影响的行数,但如果调用带输出参数的存储过程,该方法就有返回值了。
ExecuteReader()方法
这个方法执行命令,并根据使用的提供程序返回一个类型化的DataReader对象,返回的对象可以用于遍历返回的记录。
ExecuteScalar()方法
这个方法执行命令,需要从SQL语句返回一个结果,该返回一个对象,根据需要可以把对象强制转换为合适的类型。
调用存储过程
用命令对象调用存储过程,就是定义存储过程的名称,给过程的每个参数参数定义。
调用没有返回值的存储过程
CommandType.StoredProcedure
Command.Parameters 添加参数
执行使用ExecuteNonQuery
调用返回参数的存储过程
CommandType.StoredProcedure
Command.Parameters 添加输出参数
执行使用ExecuteNonQuery
如果返回的不是一个参数而是一组记录行,应该调用ExecuteReader方法。遍历所有返回记录。
参考图书《C#高级编程》