Рейтинговые книги
Читем онлайн Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 254 255 256 257 258 259 260 261 262 ... 407
class="code">CommandType, которое принимает любое значение из перечисления CommandType:

public enum CommandType

{

  StoredProcedure,

  TableDirect,

  Text // Стандартное значение.

}

При создании объекта команды SQL-запрос можно указывать как параметр конструктора или устанавливать свойство CommandText напрямую. Кроме того, когда создается объект команды, необходимо задать желаемое подключение. Его также можно указать в виде параметра конструктора либо с применением свойства Connection. Взгляните на следующий фрагмент кода:

// Создать объект команды посредством аргументов конструктора.

string sql =

    @"Select i.id, m.Name as Make, i.Color, i.Petname

         FROM Inventory i

         INNER JOIN Makes m on m.Id = i.MakeId";

SqlCommand myCommand = new SqlCommand(sql, connection);

// Создать еще один объект команды через свойства.

SqlCommand testCommand = new SqlCommand();

testCommand.Connection = connection;

testCommand.CommandText = sql;

Учтите, что в текущий момент вы еще фактически не отправили SQL-запрос базе данных AutoLot, а только подготовили состояние объекта команды для будущего использования.

В табл. 21.5 описаны некоторые дополнительные члены типа DbCommand.

Работа с объектами чтения данных

После установления активного подключения и объекта команды SQL следующим действием будет отправка запроса источнику данных. Как вы наверняка догадались, это можно делать несколькими путями. Самый простой и быстрый способ получения информации из хранилища данных предлагает тип DbDataReader (реализующий интерфейс IDataReader). Вспомните, что объекты чтения данных представляют поток данных, допускающий только чтение в прямом направлении, который возвращает по одной записи за раз. Таким образом, объекты чтения данных полезны, только когда лежащему в основе хранилищу данных отправляются SQL-операторы выборки.

Объекты чтения данных удобны, если нужно быстро пройти по большому объему данных без необходимости иметь их представление в памяти. Например, в случае запрашивания 20 000 записей из таблицы с целью их сохранения в текстовом файле помещение такой информации в объект DataSet приведет к значительному расходу памяти (поскольку DataSet хранит полный результат запроса в памяти).

Более эффективный подход предусматривает создание объекта чтения данных, который максимально быстро проходит по всем записям. Тем не менее, имейте в виду, что объекты чтения данных (в отличие от объектов адаптеров данных, которые рассматриваются позже) удерживают подключение к источнику данных открытым до тех пор, пока вы его явно не закроете.

Объекты чтения данных получаются из объекта команды с применением вызова ExecuteReader(). Объект чтения данных представляет текущую запись, прочитанную из базы данных. Он имеет метод индексатора (например, синтаксис [] в языке С#), который позволяет обращаться к столбцам текущей записи. Доступ к конкретному столбцу возможен либо по имени, либо по целочисленному индексу, начинающемуся с нуля.

В приведенном ниже примере использования объекта чтения данных задействован метод Read(), с помощью которого выясняется, когда достигнут конец записей (в случае чего он возвращает false). Для каждой прочитанной из базы данных записи с применением индексатора типа выводится модель, дружественное имя и цвет каждого автомобиля. Обратите внимание, что сразу после завершения обработки записей вызывается метод Close(), которые освобождает объект подключения.

...

// Получить объект чтения данных посредством ExecuteReader().

using(SqlDataReader myDataReader = myCommand.ExecuteReader())

{

  // Пройти в цикле по результатам.

  while (myDataReader.Read())

  {

     WriteLine($"-> Make: { myDataReader["Make"]},

         PetName: { myDataReader["PetName"]},

         Color: { myDataReader["Color"]}.");

  }

}

ReadLine();

Индексатор объекта чтения данных перегружен для приема либо значения string (имя столбца), либо значения int (порядковый номер столбца). Таким образом, текущую логику объекта чтения можно сделать яснее (и избежать жестко закодированных строковых имен), внеся следующие изменения (обратите внимание на использование свойства FieldCount):

while (myDataReader.Read())

{

  for (int i = 0; i < myDataReader.FieldCount; i++)

  {

    Console.Write(i != myDataReader.FieldCount - 1

      ? $"{myDataReader.GetName(i)} = {myDataReader.GetValue(i)}, "

      : $"{myDataReader.GetName(i)} = {myDataReader.GetValue(i)} ");

  }

  Console.WriteLine();

}

Если в настоящий момент скомпилировать проект и запустить его на выполнение, то должен отобразиться список всех автомобилей из таблицы Inventory базы данных AutoLot. В следующем выводе показано несколько начальных записей:

***** Fun with Data Readers *****

***** Info about your connection *****

Database location: .,5433

Database name: AutoLot

Timeout: 30

Connection state: Open

id = 1, Make = VW, Color = Black, Petname = Zippy

id = 2, Make = Ford, Color = Rust, Petname = Rusty

id = 3, Make = Saab, Color = Black, Petname = Mel

id = 4, Make = Yugo, Color = Yellow, Petname = Clunker

id = 5, Make = BMW, Color = Black, Petname = Bimmer

id = 6, Make = BMW, Color = Green, Petname = Hank

id = 7, Make = BMW, Color = Pink, Petname = Pinky

id = 8, Make = Pinto, Color = Black, Petname = Pete

id = 9, Make = Yugo, Color = Brown, Petname = Brownie

Получение множества результирующих наборов с использованием объекта чтения данных

Объекты чтения данных могут получать несколько результирующих наборов с применением одиночного объекта команды. Например, если вы хотите получить все строки из таблицы Inventory, а также все строки из таблицы Customers, тогда можете указать два SQL-оператора Select, разделив их точкой с запятой:

sql += ";Select * from Customers;";

На заметку! Точка с запятой в начале строки опечаткой не является. В случае использования множества операторов они должны разделяться точками с запятой. И поскольку начальный оператор не содержал точку с запятой, она добавлена здесь в начало второго оператора.

После получения объекта чтения данных можно выполнить проход по каждому результирующему набору, используя метод NextResult(). Обратите внимание, что автоматически возвращается первый результирующий набор. Таким образом, если нужно прочитать все строки каждой таблицы, тогда можно построить следующую конструкцию итерации:

do

{

  while (myDataReader.Read())

  {

    for (int i = 0; i < myDataReader.FieldCount; i++)

    {

1 ... 254 255 256 257 258 259 260 261 262 ... 407
На этой странице вы можете бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен бесплатно.

Оставить комментарий