数据阅读器(DataReader)
当执行返回结果集的命令时,需要一个方法从届国际中提取数据。处理结果集的方法有两个:第一,使用数据阅读器(DataReader);第二,同时使用数据适配器(Data Adapter)和ADO.NET数据集(DataSet)。这里我主要介绍一下数据阅读器的有关知识。
DataReader类
在ADO.NET中由每个数据提供程序实现自己的DataReader。
1.创建DataReader对象
在ADO.NET中从来不会显示地使用DataReader对象的构造函数创建DataReader对象。事实上,DataReader类没有提供公有的构造函数。人们通常调用Command类的ExecuteReader方法,这个方法将返回一个DataReader对象。下边的代码阐明了如何创建SqlDataReader对象:
DataReader类最常见的用法就是检索SQL查询或存储过程返回记录。另外DataReader是一个连接的、只向前的和只读的结果集。也就是说,当使用数据阅读器时,必须保持连接处于打开状态。除此之外,可以从头到尾便利记录集,而且也只能以这样的次序遍历。这就意味着,不能在某条记录处停下来向回移动。记录是只读的,因此数据阅读器类不提供任何修改数据库记录的方法。
这里需要特别主义的是:数据阅读器使用底层的连接,连接是它专有的。当数据阅读器打开时,不能使用对应的连接对象执行其他任何任务,例如执行另外的命令等。当阅读完数据阅读器的记录或不再需要数据阅读器时,应该立刻关闭数据阅读器。
Command对象的Execute方法有一个重载版本,那个重载版本接受命令行为参数。虽然命令文本指定返回结果集的查询,但是通过执行命令行为,可以提供一些关于想要怎么样使用结果的指令。ADO.NET在System.Data命令空间中定义了CommandBehavior枚举,其值和具体意义如下表所示:
该表的内容来自MSDN
例如下面的代码表明当关闭阅读器reader时数据连接也将同时被关闭,无需再次显式的关闭数据连接。
SqlDataReader reader=cmd.ExecuteReader(CommandBehavior.CloseConnection);
2.遍历数据阅读器中的记录
当ExcuteReader方法返回DataReader对象时,当前光标的位置在第一条记得的前面。必须调用阅读器的Read方法把光标移动到第一条记录,然后,第一条记录将变成当前记录。如果数据阅读器所包含的记录不止一条,Read方法就返回一个Boolean值true。想要移动倒下一条记录,需要再次调用Read方法。重复上述过程,知道最后一条记录,那是Read方法将返回false。经常使用while循环来遍历记录:
只要Read方法返回的值为true,就可以访问当前记录中包含的字段。
3 访问字段中的值
ADODB.NET提供了两种方法访问记录中的字段。第一种时Item属性,此属性返回由字段索引或字段名指定的字段值,第二种方法是Get方法,此方法返回由字段索引指定的字段的值。
Item属性
每一个DataReader类都定义了一个Item属性,此属性返回一个代码字段属性的对象。Item属性时DataReader类的索引。需要注意的是Item属性总是基于0开始编号的:
可以把包含字段名的字符串传入Item属性,也可以把指定字段索引的32位整数传递给Item属性。例如,如果命令是SQL Select查询:
使用下面任意一种方法,都可以得到两个被返回字段的值:
另外需要注意的是,在使用数据时需要自己负责类型转换,如下所示:
Get方法
每一个DataReader类都定义了一组Get方法,那些方法将返回适当类型的值。例如,GetInt32方法把返回的字段值作为32位整数。每一个Get方法都接受字段的索引,例如在上面的例子中,使用以下的代码可以检索UserId字段和UserName字段的值:
理论性的东西就写这么多了,下边我实例演示一下DataReader
要实现的功能,将读取所有的用户信息并将其显示出来。
(1)启动Visual Studio,新建一个网站。
(2) 在Default.aspx页面的<div></div>中加入如下代码:
<asp:Literal ID="ltlUserInfo" runat="server"></asp:Literal>
(3)在Default.aspx.cs中首先添加SqlClient的命名空间:
(4)在Page_Load事件中添加代码。
Default.aspx.cs代码全部如下:
备注:数据表XTJ_Users结构
效果如下:
DataReader类
在ADO.NET中由每个数据提供程序实现自己的DataReader。
1.创建DataReader对象
在ADO.NET中从来不会显示地使用DataReader对象的构造函数创建DataReader对象。事实上,DataReader类没有提供公有的构造函数。人们通常调用Command类的ExecuteReader方法,这个方法将返回一个DataReader对象。下边的代码阐明了如何创建SqlDataReader对象:
sqlCommand cmd=new SqlCommand(CommandText,ConnectionObject);
SqlDataReader reader=cmd.ExecuteReader();
SqlDataReader reader=cmd.ExecuteReader();
DataReader类最常见的用法就是检索SQL查询或存储过程返回记录。另外DataReader是一个连接的、只向前的和只读的结果集。也就是说,当使用数据阅读器时,必须保持连接处于打开状态。除此之外,可以从头到尾便利记录集,而且也只能以这样的次序遍历。这就意味着,不能在某条记录处停下来向回移动。记录是只读的,因此数据阅读器类不提供任何修改数据库记录的方法。
这里需要特别主义的是:数据阅读器使用底层的连接,连接是它专有的。当数据阅读器打开时,不能使用对应的连接对象执行其他任何任务,例如执行另外的命令等。当阅读完数据阅读器的记录或不再需要数据阅读器时,应该立刻关闭数据阅读器。
Command对象的Execute方法有一个重载版本,那个重载版本接受命令行为参数。虽然命令文本指定返回结果集的查询,但是通过执行命令行为,可以提供一些关于想要怎么样使用结果的指令。ADO.NET在System.Data命令空间中定义了CommandBehavior枚举,其值和具体意义如下表所示:
CloseConnection | 在执行该命令时,如果关闭关联的 DataReader 对象,则关联的 Connection 对象也将关闭。 |
Default | 此查询可能返回多个结果集。执行查询可能会影响数据库状态。Default 不设置 CommandBehavior 标志,因此调用 ExecuteReader(CommandBehavior.Default) 在功能上等效于调用 ExecuteReader()。 |
KeyInfo | 此查询返回列和主键信息。 当 KeyInfo 用于命令执行时,提供程序将为现有主键列和时间戳列的结果集附加额外的列。 当使用 KeyInfo 时,用于 SQL Server 的 .NET Framework 数据提供程序将在要执行的语句前加上 SET FMTONLY OFF 和 SET NO_BROWSETABLE ON。用户应该注意潜在的副作用,例如对 SET FMTONLY ON 语句的使用产生的干扰。有关更多信息,请参见“SQL Server 联机丛书”。 |
SchemaOnly | 查询仅返回列信息。当使用 SchemaOnly 时,用于 SQL Server 的 .NET Framework 数据提供程序将在要执行的语句前加上 SET FMTONLY ON。 |
SequentialAccess | 提供一种方法,以便 DataReader 处理包含带有大二进制值的列的行。SequentialAccess 不是加载整行,而是使 DataReader 将数据作为流来加载。然后可以使用 GetBytes 或 GetChars 方法来指定开始读取操作的字节位置以及正在返回的数据的有限的缓冲区大小。 当指定 SequentialAccess 时,尽管无需读取每个列,但是需要按照列的返回顺序读取它们。一旦已经读过返回的数据流中某个位置的内容,就不能再从 DataReader 中读取该位置或该位置之前的数据。当使用 [url=ms-help://MS.MSDNQTR.v80.chs/MS.MSDN.v80/MS.NETDEVFX.v20.chs/cpref4/html/T_System_Data_OleDb_OleDbDataReader.htm]OleDbDataReader[/url] 时,可重新读取当前列的值,直到读过它。当使用 [url=ms-help://MS.MSDNQTR.v80.chs/MS.MSDN.v80/MS.NETDEVFX.v20.chs/cpref4/html/T_System_Data_SqlClient_SqlDataReader.htm]SqlDataReader[/url] 时,一次只能读取一个列值。 |
SingleResult | 查询返回一个结果集。 |
SingleRow | 查询应返回一行。执行查询可能会影响数据库的状态。一些 .NET Framework 数据提供程序可能(但不要求)使用此信息来优化命令的性能。用 [url=ms-help://MS.MSDNQTR.v80.chs/MS.MSDN.v80/MS.NETDEVFX.v20.chs/cpref4/html/T_System_Data_OleDb_OleDbCommand.htm]OleDbCommand[/url] 对象的 [url=ms-help://MS.MSDNQTR.v80.chs/MS.MSDN.v80/MS.NETDEVFX.v20.chs/cpref4/html/O_T_System_Data_OleDb_OleDbCommand_ExecuteReader.htm]ExecuteReader[/url] 方法指定 SingleRow 时,用于 OLE DB 的 .NET Framework 数据提供程序使用 OLE DB IRow 接口(如果可用)执行绑定。否则,它使用 IRowset 接口。如果您的 SQL 语句应该只返回一行,则指定 SingleRow 还可以提高应用程序性能。在执行返回多个结果集的查询时,可以指定 SingleRow。在这种情况下,仍返回多个结果集,但每个结果集只有一行。 |
该表的内容来自MSDN
例如下面的代码表明当关闭阅读器reader时数据连接也将同时被关闭,无需再次显式的关闭数据连接。
SqlDataReader reader=cmd.ExecuteReader(CommandBehavior.CloseConnection);
2.遍历数据阅读器中的记录
当ExcuteReader方法返回DataReader对象时,当前光标的位置在第一条记得的前面。必须调用阅读器的Read方法把光标移动到第一条记录,然后,第一条记录将变成当前记录。如果数据阅读器所包含的记录不止一条,Read方法就返回一个Boolean值true。想要移动倒下一条记录,需要再次调用Read方法。重复上述过程,知道最后一条记录,那是Read方法将返回false。经常使用while循环来遍历记录:
while(reader.Read())
{
//读取数据
}
{
//读取数据
}
只要Read方法返回的值为true,就可以访问当前记录中包含的字段。
3 访问字段中的值
ADODB.NET提供了两种方法访问记录中的字段。第一种时Item属性,此属性返回由字段索引或字段名指定的字段值,第二种方法是Get方法,此方法返回由字段索引指定的字段的值。
Item属性
每一个DataReader类都定义了一个Item属性,此属性返回一个代码字段属性的对象。Item属性时DataReader类的索引。需要注意的是Item属性总是基于0开始编号的:
object FieldValue=reader[FieldName];
object FieldValue=reader[FieldIndex];
object FieldValue=reader[FieldIndex];
可以把包含字段名的字符串传入Item属性,也可以把指定字段索引的32位整数传递给Item属性。例如,如果命令是SQL Select查询:
Select UserId,UserName From XTJ_Users
使用下面任意一种方法,都可以得到两个被返回字段的值:
object userId=reader[0];
object userName=reader[1];
object userName=reader[1];
另外需要注意的是,在使用数据时需要自己负责类型转换,如下所示:
int userId=(int)reader[0];
string userName=(string)reader[1];
string userName=(string)reader[1];
Get方法
每一个DataReader类都定义了一组Get方法,那些方法将返回适当类型的值。例如,GetInt32方法把返回的字段值作为32位整数。每一个Get方法都接受字段的索引,例如在上面的例子中,使用以下的代码可以检索UserId字段和UserName字段的值:
1int userId=reader.GetInt32(0);
2string userName=reader.GetString(1);
2string userName=reader.GetString(1);
理论性的东西就写这么多了,下边我实例演示一下DataReader
要实现的功能,将读取所有的用户信息并将其显示出来。
(1)启动Visual Studio,新建一个网站。
(2) 在Default.aspx页面的<div></div>中加入如下代码:
<asp:Literal ID="ltlUserInfo" runat="server"></asp:Literal>
(3)在Default.aspx.cs中首先添加SqlClient的命名空间:
using System.Data.SqlClient;
(4)在Page_Load事件中添加代码。
Default.aspx.cs代码全部如下:
1using System;
2using System.Data;
3using System.Configuration;
4using System.Web;
5using System.Web.Security;
6using System.Web.UI;
7using System.Web.UI.WebControls;
8using System.Web.UI.WebControls.WebParts;
9using System.Web.UI.HtmlControls;
10using System.Data.SqlClient;
11public partial class _Default : System.Web.UI.Page
12{
13 protected void Page_Load(object sender, EventArgs e)
14 {
15 if (!Page.IsPostBack)
16 {
17 //定义输出消息
18 string showMessage = "";
19 //新建连接对象
20 SqlConnection conn = new SqlConnection();
21 conn.C;
22 //新建命令字符串
23 string selectQuery = "Select UserId,UserName,UserPassword From XTJ_Users";
24 //新建命令对象
25 SqlCommand cmd = new SqlCommand(selectQuery, conn);
26 conn.Open();
27 //关闭阅读器时将自动关闭数据库连接
28 SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
29 //循环读取信息
30 while (reader.Read())
31 {
32 showMessage += "<font color=\"red\">用户Id:</font>" + reader[0].ToString() + " ";
33 showMessage += "<font color=\"red\">用户姓名:</font>" + reader["UserName"].ToString() + " ";
34 showMessage += "<font color=\"red\">用户密码:</font>" + reader.GetString(2) + "";
35 showMessage += "<br/>";
36 }
37 //关闭数据阅读器
38 reader.Close();
39 //测试数据连接是否已经关闭
40 if (conn.State == ConnectionState.Closed)
41 {
42 showMessage += "数据连接已经关闭。<br/>";
43 }
44 ltlUserInfo.Text = showMessage;
45 }
46 }
47}
2using System.Data;
3using System.Configuration;
4using System.Web;
5using System.Web.Security;
6using System.Web.UI;
7using System.Web.UI.WebControls;
8using System.Web.UI.WebControls.WebParts;
9using System.Web.UI.HtmlControls;
10using System.Data.SqlClient;
11public partial class _Default : System.Web.UI.Page
12{
13 protected void Page_Load(object sender, EventArgs e)
14 {
15 if (!Page.IsPostBack)
16 {
17 //定义输出消息
18 string showMessage = "";
19 //新建连接对象
20 SqlConnection conn = new SqlConnection();
21 conn.C;
22 //新建命令字符串
23 string selectQuery = "Select UserId,UserName,UserPassword From XTJ_Users";
24 //新建命令对象
25 SqlCommand cmd = new SqlCommand(selectQuery, conn);
26 conn.Open();
27 //关闭阅读器时将自动关闭数据库连接
28 SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
29 //循环读取信息
30 while (reader.Read())
31 {
32 showMessage += "<font color=\"red\">用户Id:</font>" + reader[0].ToString() + " ";
33 showMessage += "<font color=\"red\">用户姓名:</font>" + reader["UserName"].ToString() + " ";
34 showMessage += "<font color=\"red\">用户密码:</font>" + reader.GetString(2) + "";
35 showMessage += "<br/>";
36 }
37 //关闭数据阅读器
38 reader.Close();
39 //测试数据连接是否已经关闭
40 if (conn.State == ConnectionState.Closed)
41 {
42 showMessage += "数据连接已经关闭。<br/>";
43 }
44 ltlUserInfo.Text = showMessage;
45 }
46 }
47}
备注:数据表XTJ_Users结构
效果如下: