可以使用 ADO.NET DataReader 从数据库中检索只读、只进的数据流。因为每次在内存中始终只有一行,所以使用 DataReader 可提高应用程序的性能并减少系统开销。
当创建 Command 对象的实例后,可调用 Command.ExecuteReader 从数据源中检索行,从而创建一个 DataReader,如以下示例所示。
1 | SqlDataReader myReader = myCommand.ExecuteReader(); |
使用 DataReader 对象的 Read 方法可从查询结果中获取行。通过向 DataReader 传递列的名称或序号引用,可以访问返回行的每一列。不过,为了实现最佳性能,DataReader 提供了一系列方法,它们将使您能够访问其本机数据类型(GetDateTime、GetDouble、GetGuid、GetInt32 等)形式的列值。有关类型化访问器方法的列表,请参阅
以下代码示例循环访问一个 DataReader 对象,并从每个行中返回两个列。
1 2 3 | while (myReader.Read()) Console.WriteLine( "\t{0}\t{1}" , myReader.GetInt32(0), myReader.GetString(1)); myReader.Close(); |
DataReader 提供未缓冲的数据流,该数据流使过程逻辑可以有效地按顺序处理从数据源中返回的结果。由于数据不在内存中缓存,所以在检索大量数据时,DataReader 是一种适合的选择。
关闭 DataReader
每次使用完 DataReader 对象后都应调用 Close 方法。
如果 Command 包含输出参数或返回值,那么在 DataReader 关闭之前,将无法访问这些输出参数或返回值。
请注意,当 DataReader 打开时,该 DataReader 将以独占方式使用 Connection。在初始 DataReader 关闭之前,将无法对 Connection 执行任何命令(包括创建另一个 DataReader)。
多个结果集
如果返回的是多个结果集,DataReader 会提供 NextResult 方法来按顺序循环访问这些结果集,如以下代码示例所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | SqlCommand myCMD = new SqlCommand( "SELECT CategoryID, CategoryName FROM Categories;" + "SELECT EmployeeID, LastName FROM Employees" , nwindConn); nwindConn.Open(); SqlDataReader myReader = myCMD.ExecuteReader(); do { Console.WriteLine( "\t{0}\t{1}" , myReader.GetName(0), myReader.GetName(1)); while (myReader.Read()) Console.WriteLine( "\t{0}\t{1}" , myReader.GetInt32(0), myReader.GetString(1)); } while (myReader.NextResult()); myReader.Close(); nwindConn.Close(); |
从 DataReader 中获取架构信息
当 DataReader 打开时,可以使用 GetSchemaTable 方法检索有关当前结果集的架构信息。GetSchemaTable 将返回一个填充了行和列的 DataTable 对象,这些行和列包含当前结果集的架构信息。对于结果集的每一列,DataTable 都将包含一行。架构表行的每一列都映射到在结果集中返回的列的属性,其中 ColumnName 是属性的名称,而列的值为属性的值。以下代码示例为 DataReader 写出架构信息。
1 2 3 4 5 6 7 8 | DataTable schemaTable = myReader.GetSchemaTable(); foreach (DataRow myRow in schemaTable.Rows) { foreach (DataColumn myCol in schemaTable.Columns) Console.WriteLine(myCol.ColumnName + " = " + myRow[myCol]); Console.WriteLine(); } |
联系客服