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

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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 255 256 257 258 259 260 261 262 263 ... 407
Перейти на страницу:
class="code">      Console.Write(i != myDataReader.FieldCount - 1

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

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

    }

    Console.WriteLine();

  }

  Console.WriteLine();

} while (myDataReader.NextResult());

К этому моменту вы уже должны лучше понимать функциональность, предлагаемую объектами чтения данных. Не забывайте, что объект чтения данных способен обрабатывать только SQL-операторы Select; его нельзя применять для изменения существующей таблицы базы данных с использованием запросов Insert, Update или Delete. Модификация существующей базы данных требует дальнейшего исследования объектов команд.

Работа с запросами создания обновления и удаления

Метод ExecuteReader() извлекает объект чтения данных, который позволяет просматривать результаты SQL-оператора Select с помощью потока информации, допускающего только чтение в прямом направлении. Однако если необходимо отправить операторы SQL, которые в итоге модифицируют таблицу данных (или любой другой отличающийся от запроса оператор SQL, такой как создание таблицы либо выдача разрешений), то потребуется вызов метода ExecuteNonQuery() объекта команды. В зависимости от формата текста команды указанный единственный метод выполняет вставки, обновления и удаления.

На заметку! Говоря формально, "отличающийся от запроса" означает оператор SQL, который не возвращает результирующий набор. Таким образом, операторы Select являются запросами, тогда как Insert, Update и Delete — нет. С учетом сказанного метод ExecuteNonQuery() возвращает значение int, которое представляет количество строк, затронутых операторами, а не новый набор записей.

Все примеры взаимодействия с базами данных, рассмотренные в настоящей главе до сих пор, располагали только открытыми подключениями и применяли их для извлечения данных. Это лишь одна часть работы с базами данных; инфраструктура доступа к данным не приносила бы так много пользы, если бы полностью не поддерживала также функциональность создания, чтения, обновления и удаления (create, read, update, delete — CRUD). Далее вы научитесь пользоваться такой функциональностью, применяя вызовы ExecuteNonQuery().

Начните с создания нового проекта библиотеки классов C# по имени AutoLot.DAL (сокращение от AutoLot Data Access Layer — уровень доступа к данным AutoLot), удалите стандартный файл класса и добавьте в проект пакет Microsoft.Data.SqlClient.

Перед построением класса, который будет управлять операциями с данными, сначала понадобится создать класс С#, представляющий запись из таблицы Inventory со связанной информацией Make.

Создание классов Car и CarViewModel

В современных библиотеках доступа к данным применяются классы (обычно называемые моделями или сущностями), которые используются для представления и транспортировки данных из базы данных. Кроме того, классы могут применяться для представления данных, которое объединяет две и большее количество таблиц, делая данные более значимыми. Сущностные классы используются при работе с каталогом базы данных (для операторов обновления), а классы модели представления применяются для отображения данных в осмысленной манере. В следующей главе вы увидите, что такие концепции являются основой инфраструктур объектно-реляционного отображения (object relational mapping — ORM) вроде Entity Framework Core, но пока вы просто собираетесь создать одну модель (для низкоуровневой строки хранилища) и одну модель представления (объединяющую строку хранилища и связанные данные в таблице Makes). Добавьте в проект новую папку по имени Models и поместите в нее два файла, Car.cs и CarViewModel.cs, со следующим кодом:

// Car.cs

namespace AutoLot.Dal.Models

{

  public class Car

  {

    public int Id { get; set; }

    public string Color { get; set; }

    public int MakeId { get; set; }

    public string PetName { get; set; }

    public byte[] TimeStamp {get;set;}

  }

}

// CarViewModel.cs

namespace AutoLot.Dal.Models

{

  public class CarViewModel : Car

  {

    public string Make { get; set; }

  }

}

На заметку! Если вы не знакомы с типом данных TimeStamp в SQL Server (который отображается на byte[] в С#), то беспокоиться об этом не стоит. Просто знайте, что он используется для проверки параллелизма на уровне строк и раскрывается вместе с Entity Framework Core.

Новые классы будут применяться вскоре. 

Добавление класса InventoryDal

Далее добавьте новую папку по имени DataOperations. Поместите в нее файл класса по имени InventoryDal.cs и измените класс на public. В этом классе будут определены разнообразные члены, предназначенные для взаимодействия с таблицей Inventory базы данных AutoLot. Наконец, импортируйте следующие пространства имен:

using System; 

using System.Collections.Generic;

using System.Data;

using AutoLot.Dal.Models;

using Microsoft.Data.SqlClient;

Добавление конструкторов

Создайте конструктор, который принимает строковый параметр (connectionString) и присваивает его значение переменой уровня класса. Затем создайте конструктор без параметров, передающий стандартную строку подключения другому конструктору В итоге вызывающий код получит возможность изменения строки подключения, если стандартный вариант не подходит. Ниже показан соответствующий код:

namespace AuoLot.Dal.DataOperations

{

  public class InventoryDal

  {

    private readonly string _connectionString;

    public InventoryDal() : this(

      @"Data Source=.,5433;User Id=sa;Password=P@ssw0rd;

      Initial Catalog=AutoLot")

    {

    }

    public InventoryDal(string connectionString)

      => _connectionString = connectionString;

  }

}

Открытие и закрытие подключения

Добавьте переменную уровня класса, которая будет хранить подключение, применяемое кодом доступа к данным. Добавьте также два метода: один для открытия подключения (OpenConnection()) и еще один для закрытия подключения (CloseConnection()). В методе CloseConnection() проверьте состояние подключения и если оно не закрыто, тогда вызовите метод Close() на объекте подключения. Вот как выглядит код:

private SqlConnection _sqlConnection = null;

private void OpenConnection()

{

  _sqlConnection = new SqlConnection

  {

    ConnectionString = _connectionString

  };

  _sqlConnection.Open();

}

private void CloseConnection()

{

  if (_sqlConnection?.State != ConnectionState.Closed)

  {

    _sqlConnection?.Close();

  }

}

Ради краткости в большинстве методов класса InventoryDal не будут применяться блоки try/catch для обработки возможных исключений, равно как не будут генерироваться специальные исключения для сообщения о разнообразных проблемах при выполнении (скажем, неправильно сформированная строка подключения). Если бы строилась библиотека

1 ... 255 256 257 258 259 260 261 262 263 ... 407
Перейти на страницу:

Комментарии
Минимальная длина комментария - 20 знаков. В коментария нецензурная лексика и оскорбления ЗАПРЕЩЕНЫ! Уважайте себя и других!
Комментариев еще нет. Хотите быть первым?