首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

21.4  快速数据访问:数据读取器

数据读取器(data reader)是从一个数据源中选择某些数据的最简单快捷的方法,但这也是功能最弱的一个方法。不能直接实例化数据阅读器,即实例是调用ExecuteReader()方法后从相应数据库的命令对象中返回的。

下面的代码说明了如何从Northwind数据库的Customer表中选择数据。这个示例连接了数据库,选择许多记录,循环所选的记录,并把它们输出到控制台上。

这个示例使用OLE DB提供程序作为一个来自SQL提供程序的简要的数据暂存器。在大多数情况下,OleDbClient类与SqlClient类是一对一的关系,例如OleDbConnection对象就类似于在前面的示例中所使用的SqlConnection对象。

要对OLE DB数据源执行命令,应使用OleDbCommand类。下面的代码执行一个简单的SQL语句,读取记录,返回一个OleDbDataReader对象。

注意下面的第二个using语句使OleDb类可用。

using System;

using System.Data.OleDb;

目前所利用的所有数据提供程序都在同一个DLL所以只需要引用System.Data.dll程序集就可以导入本节使用的所有类

public class DataReaderExample

{

   public static void Main(string[] args)

   {

      string source = "Provider=SQLOLEDB;" +

                   "server=(local)\\NetSDK;" +

                   " integrated security=SSPI;" +

                   "database=northwind";

      string select = "SELECT ContactName,CompanyName FROM Customers";

      OleDbConnection conn = new OleDbConnection(source);

      conn.Open();

      OleDbCommand cmd = new OleDbCommand(select , conn);

      OleDbDataReader aReader = cmd.ExecuteReader();

      while(aReader.Read())

         Console.WriteLine("'{0}' from {1}" ,

                           aReader.GetString(0) , aReader.GetString(1));

      aReader.Close();

      conn.Close();

   }

}

前面的代码包含其他章节介绍的许多熟悉的C#功能。要编译该示例,使用下面的命令:

csc /t:exe /debug+ DataReaderExample.cs /r:System.Data.dll

在前面的示例中,下面的代码根据源连接字符串,创建一个新OLE DB.NET数据库连接:

   OleDbConnection conn = new OleDbConnection(source);

   conn.Open();

   OleDbCommand cmd = new OleDbCommand(select, conn);

第三行根据特定的Select语句创建一个新OleDbCommand对象以及执行命令时所使用的数据库连接。当有一个有效的命令时,就需要执行它,返回一个初始化了的OleDbDataReader

   OleDbDataReader aReader = cmd.ExecuteReader();

OleDbDataReader是一个只向前的连接游标即只能沿着一个方向遍历记录而使用的数据库连接一直打开直到关闭DataReader为止。

提示:

OleDbDataReader会使数据库连接一直处于打开状态,直到显式关闭为止。

OleDbDataReader类不能直接实例化,它总是通过OleDbCommand类的ExecuteReader方法调用而返回。打开了一个数据读取器后,就可以用各种方式访问包含在该读取器中的数据。

关闭OleDbDataReader对象(显式调用Close()或通过垃圾收集器收集对象)时,底层的连接也会关闭。这取决于调用了哪个ExecuteReader()方法。如果调用了ExecuteReader()方法,并传递了CommandBehavior.CloseConnection,就会在关闭读取器的时候关闭连接。

OleDbDataReader类有一个索引器,可以使用常见的数组语法访问任何字段(但不是类型安全的访问)

   object o = aReader[0];

   object o = aReader["CategoryID"];

假定CategoryID字段是SELECT语句中用于生成阅读器的第一个字段那么这两行语句的功能就是相同的但后者比前者慢一些。为了验证这一点,编写一个简单的测试程序,从打开的数据读取器上对同一列进行一百万次的迭代访问,获取一些足够大的数字,虽然在一个循环中可能并不会对同一列访问一百万次,但按每秒来计算,就可能编写出最佳的代码。

另外,数字索引器平均每0.09秒就进行一百万次的访问,而文本索引器则需要0.63秒。原因是文本方法是从模式的内部查找列号,再使用列号的顺序进行访问。如果知道这个区别,就可以更好地访问数据。

是否应使用数字索引器?也许,但还有一种更好的方式。

除了上面给出的索引器外,OleDbDataReader还有一组类型安全的方法可以用于读取列,这些方法都可以进行自我解释,且都以Get开头。有一些方法可以读取大多数类型的数据,例如GetInt32 GetFloatGetGuid等。

前面使用GetInt32的一百万次迭代用了0.06秒,数字索引器中的系统开销是获取数据类型,调用与GetInt32相同的代码,然后装箱(本实例是拆箱)为一个整数。如果以前知道这种模式,并希望使用加密数字而不是列名,以避免对每个列访问使用类型安全的函数,这样运行速度就会比使用文本格式的列名快10(选择同一列的上百万个副本)

在可维护性和速度之间有一个折中的问题。如果必须使用数字索引器,就应在类的范围内为每一个要访问的列定义常量。上面的代码可以用于从任何OLE DB数据库中选择数据,但有许多SQL Server的特定类可以使用,但其便利性有明显的损失。

下面的示例与上一示例基本相同,但在这个实例中用SQL提供程序和SQL类的引用替换了OLE DB提供程序和对OLE DB类的所有引用。代码的变化已经突出显示出来了。该示例在04_DataReaderSql目录下:

using System;

using System.Data.SqlClient;

public class DataReaderSql

{

   public static int Main(string[] args)

   {

      string source ="server=(local)\\NetSDK;" +

                  " integrated security=SSPI;" +

                  "database=northwind";

      string select = "SELECT ContactName,CompanyName FROM Customers";

      SqlConnection conn = new SqlConnection(source);

      conn.Open();

      SqlCommand cmd = new SqlCommand(select , conn);

      SqlDataReader aReader = cmd.ExecuteReader();

      while(aReader.Read())

         Console.WriteLine("'{0}' from {1}" , aReader.GetString(0) ,

                            aReader.GetString(1));

      aReader.Close();

      conn.Close();

      return 0;

   }

}

注意区别是什么?如果键入这些代码,用sql替换所有的OleDb,改变数据源字符串,重新编译。这是很容易的。

Sql提供程序的索引器进行相同的性能测试,这次数字索引器也使用0.13秒就完成了百万次的访问,基于索引器的字符串运行了0.65秒,本机的Sql提供程序要比OleDb快,直到我在.NET版本中测试这一部分,情况都是这样。可以肯定这是不正常的,因为我使用的是最简单的测试(对同一个值选择1 000 000),在托管SQL提供程序上进行真实的测试,会得到更好的性能。

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论