Поделиться через


Извлечение данных с помощью DataReader

Область применения: платформа .NET Framework .NET Standard

Скачать ADO.NET

Для извлечения данных с помощью объекта DataReader создайте экземпляр объекта Command, а затем создайте поставщика DataReader, вызвав метод Command.ExecuteReader для получения строк из источника данных. Объект DataReader предоставляет небуферизованный поток данных, позволяющий процедурам последовательно обрабатывать результаты из источника данных.

Примечание.

Объект DataReader хорошо подходит для извлечения больших объемов данных, поскольку данные не кэшируются в памяти.

В следующем примере иллюстрируется использование объекта DataReader, где reader представляет допустимый DataReader, а command представляет допустимый объект Command.

reader = command.ExecuteReader();  

Используйте метод DataReader.Read для получения строки из результатов запроса. Доступ к отдельным столбцам возвращенной строки осуществляется по имени или порядковому номеру столбца через объект DataReader. Однако для максимальной производительности объект DataReader предоставляет ряд методов, позволяющих обращаться к значениям столбцов в их собственных типах данных (GetDateTime, GetDouble, GetGuid, GetInt32 и т. д.). Список типизированных методов доступа в объекте DataReader для конкретных поставщиков данных см. в разделе 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. Невозможно выполнять какие-либо команды для Connection, включая создание другого объекта DataReader, пока исходный объект DataReader не будет закрыт.

Примечание.

В методе Finalize вашего класса нельзя вызывать методы Close или Dispose объектов Connection, DataReader или любого другого управляемого объекта. В методе завершения следует только освобождать неуправляемые ресурсы, которыми ваш класс непосредственно владеет. Если класс не владеет какими-либо неуправляемыми ресурсами, не включайте в его определение метод Finalize. Дополнительные сведения см. в статье Сборка мусора.

Извлечение нескольких результирующих наборов при помощи NextResult

Если объект DataReader возвращает несколько результирующих наборов, используйте метод NextResult для просмотра наборов результатов по порядку. В следующем примере показан объект SqlDataReader, обрабатывающий результаты двух инструкций SELECT с помощью метода ExecuteReader.

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();
    }
}

См. также