由 DataReader 擷取的資料

適用於: .NET Framework .NET .NET 標準

下載 ADO.NET

若要使用 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

當 Close() 物件使用完畢之後,請務必呼叫 DataReader 方法。

注意

如果您的 Command 包含輸出參數或傳回值,則必須等到 DataReader 關閉後才能使用這些值。

重要

在 DataReader 開啟期間,Connection 只能供該 DataReader 使用。 必須等到原始 DataReader 關閉後,才能執行 Connection 的任何命令 (包括建立其他 DataReader)。

注意

請勿在您類別的 Finalize 方法中,對 Connection、DataReader 或任何其他受控物件呼叫 Close 或 Dispose。 在解構函式中,僅釋放類別直接擁有的非受控資源。 如果類別未擁有任何 Unmanaged 資源,請不要在類別定義中包含 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();
    }
}