按 DataReader 检索数据
适用于: .NET Framework .NET .NET Standard
若要使用 DataReader 检索数据,请创建 Command 对象的实例,然后通过调用 Command.ExecuteReader 创建一个 DataReader,以便从数据源检索行 。 DataReader 提供未缓冲的数据流,该数据流使过程逻辑可以有效地按顺序处理从数据源中返回的结果。
注意
由于数据不在内存中缓存,所以在检索大量数据时,DataReader 是一种适合的选择。
下面的示例演示如何使用 DataReader,其中 reader
表示有效的 DataReader,而 command
表示有效的 Command 对象。
reader = command.ExecuteReader();
使用 DataReader.Read 方法从查询结果中获取行。 通过向 DataReader 传递列的名称或序号,可以访问返回行的每一列。 不过,为了实现最佳性能,DataReader 提供了一系列方法,将使你能够访问其本机数据类型(GetDateTime、GetDouble、GetGuid、GetInt32 等)的列值 。 有关数据提供程序特定的 DataReaders 的类型化访问器方法列表,请参阅 SqlDataReader。 已知基础数据类型时,如果使用类型化访问器方法,将减少在检索列值时所需的类型转换量。
以下示例循环访问一个 DataReader 对象,并从每个行中返回两个列。
static void HasRows(SqlConnection connection)
{
using (connection)
{
SqlCommand command = new SqlCommand(
"SELECT CategoryID, CategoryName FROM Categories;",
connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
// Check if the DataReader has any row.
if (reader.HasRows)
{
// Obtain a row from the query result.
while (reader.Read())
{
Console.WriteLine("{0}\t{1}", reader.GetInt32(0),
reader.GetString(1));
}
}
else
{
Console.WriteLine("No rows found.");
}
// Always call the Close method when you have finished using the DataReader object.
reader.Close();
}
}
关闭 DataReader
使用完 DataReader
对象后,请始终调用 Close()
方法。
注意
如果 Command 包含输出参数或返回值,那么在 DataReader 关闭之前,将无法访问这些值 。
重要
当 DataReader 打开时,该 DataReader 将以独占方式使用 Connection 。 在原始 DataReader 关闭之前,将无法对 Connection 执行任何命令(包括创建另一个 DataReader) 。
备注
不要在类的 Finalize 方法中对 Connection、DataReader 或任何其他托管对象调用 Close 或 Dispose 。 在终结器中,仅释放类直接拥有的非托管资源。 如果类不拥有任何非托管资源,则不要在类定义中包含 Finalize 方法。 有关详细信息,请参阅垃圾回收。
使用 NextResult 检索多个结果集
如果 DataReader 返回多个结果集,请调用 NextResult 方法来按顺序循环访问这些结果集 。 以下示例显示 SqlDataReader 如何使用 ExecuteReader 方法处理两个 SELECT 语句的结果。
static void RetrieveMultipleResults(SqlConnection connection)
{
using (connection)
{
SqlCommand command = new SqlCommand(
"SELECT CategoryID, CategoryName FROM dbo.Categories;" +
"SELECT EmployeeID, LastName FROM dbo.Employees",
connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
// Check if the DataReader has any row.
while (reader.HasRows)
{
Console.WriteLine("\t{0}\t{1}", reader.GetName(0),
reader.GetName(1));
// Obtain a row from the query result.
while (reader.Read())
{
Console.WriteLine("\t{0}\t{1}", reader.GetInt32(0),
reader.GetString(1));
}
// Hop to the next result-set.
reader.NextResult();
}
// Always call the Close method when you have finished using the DataReader object.
reader.Close();
}
}
从 DataReader 中获取架构信息
当 DataReader 打开时,可以使用 GetSchemaTable 方法检索有关当前结果集的架构信息 。 GetSchemaTable 将返回一个填充了行和列的 DataTable 对象,这些行和列包含当前结果集的架构信息。 对于结果集的每一列,DataTable 都包含一行。 架构表的每一列都映射到在结果集的行中返回的列的属性,其中 ColumnName 是属性的名称,而列的值为属性的值。 以下示例为 DataReader 编写架构信息。
static void GetSchemaInfo(SqlConnection connection)
{
using (connection)
{
SqlCommand command = new SqlCommand(
"SELECT CategoryID, CategoryName FROM Categories;",
connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
// Retrieve schema information about the current result-set.
DataTable schemaTable = reader.GetSchemaTable();
foreach (DataRow row in schemaTable.Rows)
{
foreach (DataColumn column in schemaTable.Columns)
{
Console.WriteLine(String.Format("{0} = {1}",
column.ColumnName, row[column]));
}
}
// Always call the Close method when you have finished using the DataReader object.
reader.Close();
}
}