C#. ADO .NET. Клас DbDataReader

Приєднаний режим (connected mode). Клас DbDataReader


Зміст


1. Призначення класу DbDataReader

Клас DbDataReader надає в користування засоби читання даних у приєднаному режимі. Об’єкт класу DbDataReader призначений для читання записів (рядків) з таблиці бази даних. Читання здійснюється в момент, коли відкрите з’єднання з базою даних. Клас реалізує однонаправлене послідовне читання. Порівняно з об’єктом типу DataSet даний клас забезпечує кращу продуктивність при доступі до даних за рахунок зниження накладних витрат.

Об’єкт DataReader не підходить для оперування даними між різними рівнями додатку, оскільки при підключенні цього об’єкту з’єднання залишається відкритим.

 

2. Аналіз методів та властивостей

При читанні даних клас DataReader використовує ряд властивостей та методів.

Властивості класу DataReader наведені нижче.

Властивість Тип даних Пояснення
Depth Int32 Визначає ступінь вкладеності поточного рядка. Доступно тільки для читання
FieldCount Int32 Кількість полів в об’єкті DataReader. Доступно тільки для читання
HasRows Boolean Вказує, чи повернув запит DbCommand записи. Доступне тільки для читання
IsClosed Boolean Вказує, чи закритий об’єкт DataReader. Тільки для читання
Item Object Повертає вміст кожного поля поточного запису. Тільки для читання
RecordAffected Int32 Вказує кількість записів, що були задіяні виконаними запитами. Ця властивість Тільки для читання

Методи класу DbDataReader наступні.

Метод Пояснення
Close Закриває об’єкт DbDataReader

Get<DataType>

GetString,

GetInt32,

GetDouble,

Повертає вміст заданого поля поточного рядка на основі порядкового номеру цього поля. В методі задається тип вказаного поля

string strStudentName;
SqlDataReader rdr;

...

strStudentName = rdr.GetString(intStudentNameIndex);

або

strStudentName = (string)rdr.GetValue(intStudentNameIndex);
GetBytes Повертає з вказаного поля поточного запису масив байт
GetChars Повертає з вказаного поля поточного запису масив символів
GetData Повертає новий об’єкт DbDataReader на основі заданого поля
GetDataTypeName Повертає назву типу даних поля на основі порядкового номеру поля в записі
GetFieldType Повертає тип даних поля за порядковим номером поля
GetName Повертає ім’я поля за його порядковим номером
GetOrdinal Повертає порядковий номер поля на основі його імені
GetValue Повертає значення поля за його порядковим номером як тип даних .NET
GetValues Приймає масив, з допомогою якого об’єкт типу DbDataReader повертає вміст поточного стовпця. При виклику повертає 32 бітове ціле число, що відповідає кількості записів у масиві

SqlDataReader rdr = command.ExecuteReader();
object[] aData = new object[rdr.FileCount];
while (rdr.Read())
{
  rdr.GetValues(aData);
  Console.WriteLine(aData[0].ToString());
}
IsDbNull Вказує, чи містить поле значення Null
NextResult Використовується у випадках, якщо є пакетний запит, який повертає декілька наборів результатів. Метод реалізує перехід до наступного набору результатів
Read Здійснює перехід до наступного запису

Об’єкт типу DataReader може отримувати дані з різних джерел, в тому числі з SQL-запиту, що міститься в об’єкті типу Command (DbCommand, SqlCommand, OledbCommand, OdbcCommand). Після отримання даних існує можливість відмінити зчитування цих даних з допомогою методу Cancel().

 

3. Приклад отримання даних

У прикладі демонструється читання даних з бази даних з іменем MyDatabase. У базі даних створено таблицю з іменем Table1, яка має структуру з даними, що складається з 3-х стовпців.

Стовпці таблиці мають наступне призначення

  • Id – унікальний ідентифікатор, автоінкрементне поле;
  • Name – прізвище та ім’я студента;
  • Address – адреса студента.

Рядки таблиці заповнені значеннями як показано в таблиці.

Id Name Address
1 Student1 Address-01
2 Student2 Address-02
3 Student3 Address-03

Щоб вивести усі рядки та стовпці таблиці в компоненті ListBox для додатку типу Windows Forms можна використати, наприклад, такий код.

private void GetDataFromDataBase()
{
  // Читає дані з бази даних
  // 1. Рядок запиту
  string queryStr = "SELECT * FROM [dbo].[Table1]";

  // 2. Рядок підключення
  string connStr = @"Data Source=(localdb)\ProjectModels;" +
    "Initial Catalog=MyDatabase;Integrated Security=True;";

  // 3. Отримати дані
  using (SqlConnection connection =
    new SqlConnection(connStr))
  {
    try
    {
      // створити команду на мові SQL
      DbCommand command = connection.CreateCommand();
      command.CommandText = queryStr;
      command.CommandType = CommandType.Text;

      // Відкрити з'єднання
      connection.Open();

      // Отримати дані - клас DbDataReader
      DbDataReader dataReader = command.ExecuteReader();

      // Вивести дані в listBox1
      listBox1.Items.Clear();
      while (dataReader.Read())
      {
        listBox1.Items.Add(dataReader[0].ToString() + " - " +
        dataReader[1].ToString());
      }
    }
    catch (Exception e)
    {
      MessageBox.Show(e.Message);
    }
    finally
    {
      // Закрити з'єднання
      connection.Close();
    }
  }
}

 

4. Метод GetName(). Поле FieldCount. Отримати ім’я стовпця в таблиці

Для того, щоб отримати ім’я поля з таблиці бази даних, потрібно використати метод GetName(). Відповідно кількість полів таблиці визначається з допомогою властивості FieldCount, яка доступна тільки для читання.

Наприклад, для наступної таблиці

Id Name Address

виклик методу з об’єкту DataReader з іменем dataReader

dataReader.GetName(0);

поверне рядок “Id”.

А виклик

dataReader.GetName(2);

поверне рядок “Address”.

У нижченаведеному прикладі наводиться фрагмент коду, який виводить імена усіх полів таблиці з іменем Table1 бази даних MyDatabase. Поля відображаються в компоненті ListBox. Приклад реалізовано для додатку типу Windows Forms.

private void button7_Click(object sender, EventArgs e)
{
  // Отримати перелік імен полів на основі результату SQL-запиту та додати їх в ListBox

  // 1. Рядок підключення
  string connStr = @"Data Source=(localdb)\ProjectModels;" +
    "Initial Catalog=MyDatabase;Integrated Security=True;";

  // 2. Текст SQL-запиту
  string strSQL = "SELECT * FROM [dbo].[Table1]";

  // 3. Підключитись до бази даних та отримати дані
  using (SqlConnection connection =
    new SqlConnection(connStr))
  {
    try
    {
      // створити команду на мові SQL
      DbCommand command = connection.CreateCommand();
      command.CommandText = strSQL;
      command.CommandType = CommandType.Text;

      // Відкрити з'єднання
      connection.Open();

      // Отримати дані - клас DbDataReader
      DbDataReader dataReader = command.ExecuteReader();

      // Вивести імена стовпців таблиці в listBox1
      listBox1.Items.Clear();

      // FieldCount - кількість стовпців у таблиці, з якої зчитуються дані
      for (int i = 0; i < dataReader.FieldCount; i++) // перебір всіх полів
      {
        // Отримати ім'я поля
        string s = dataReader.GetName(i);

        // Вивести ім'я поля в ListBox
        listBox1.Items.Add(s);
      }

      // Закрити об'єкт dataReader
      dataReader.Close();
    }
    catch (Exception ex)
    {
      MessageBox.Show(ex.Message);
    }
    finally
    {
      // Закрити з'єднання
      connection.Close();
    }
  }
}

 

5. Метод GetFieldType(). Отримати назву типу даних поля (стовпця) на основі його порядкового номеру (0, 1, 2, …) як типу .NET

Метод GetFieldType() повертає екземпляр типу Type з заповненими даними про тип поля. Загальна форма оголошення методу наступна

Type DbDataReader.GetFieldType(int ordinal);

тут

  • ordinal – порядковий номер стовпця (поля) у таблиці, яка містить рядки, що представлені об’єктом DataReader.

Нижченаведений приклад демонструє читання типів даних усіх полів заданої таблиці.

private void button8_Click(object sender, EventArgs e)
{
  // Отримати назву типу даних поля
  // 1. Рядок підключення
  string connStr = @"Data Source=(localdb)\ProjectModels;" +
    "Initial Catalog=Database4;Integrated Security=True;";

  // 2. Текст SQL-запиту
  string strSQL = "SELECT * FROM [dbo].[Table1]";

  // 3. Підключитись до бази даних та отримати дані
  using (SqlConnection connection =
    new SqlConnection(connStr))
  {
    try
    {
      // створити команду на мові SQL
      DbCommand command = connection.CreateCommand();
      command.CommandText = strSQL;
      command.CommandType = CommandType.Text;

      // Відкрити з'єднання
      connection.Open();

      // Отримати дані - клас DbDataReader
      DbDataReader dataReader = command.ExecuteReader();

      // Вивести імена типів даних стовпців таблиці у listBox1
      listBox1.Items.Clear();

      // FieldCount - кількість стовпців у таблиці, з якої зчитуються дані
      for (int i = 0; i < dataReader.FieldCount; i++) // перебір всіх полів
      {
        // Отримати ім'я поля
        string s = dataReader.GetFieldType(i).Name;

        // Вивести ім'я поля в ListBox
        listBox1.Items.Add(s);
      }

      // Закрити об'єкт dataReader
      dataReader.Close();
    }
    catch (Exception ex)
    {
      MessageBox.Show(ex.Message);
    }
    finally
    {
      // Закрити з'єднання
      connection.Close();
    }
  }
}

Для таблиці, представленої у п.п. 3-4 результатом додавання полів у ListBox є рядки

Int32
String
String

 

6. Метод GetDataTypeName(). Отримати назву типу даних в базі даних на основі порядкового номеру (0, 1, 2, …)

Загальна форма оголошення методу GetDataTypeName() має вигляд:

string GetDataTypeName(int ordinal);

Фрагмент, що читає перелік типів даних з об’єкту dataReader типу DbDataReader та записує їх до компонента ListBox (додаток типу Windows Forms).

...

// Вивести імена типів даних стовпців таблиці у listBox1
listBox1.Items.Clear();

// FieldCount - кількість стовпців у таблиці, з якої зчитуються дані
for (int i = 0; i < dataReader.FieldCount; i++) // перебір всіх полів
{
  // Отримати ім'я поля
  string s = dataReader.GetDataTypeName(i);
  listBox1.Items.Add(s);
}

...

Для таблиці даних з пунктів 3, 4 результат програми буде

int
nchar
nchar

 


Споріднені теми