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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 257 258 259 260 261 262 263 264 265 ... 407
Inventory where Id = '{id}'";

  using (SqlCommand command = new SqlCommand(sql, _sqlConnection))

  {

    try

    {

      command.CommandType = CommandType.Text;

      command.ExecuteNonQuery();

    }

    catch (SqlException ex)

    {

      Exception error = new Exception("Sorry! That car is on order!", ex);

      throw error;

    }

  }

  CloseConnection();

}

Добавление логики обновления

Когда речь идет об обновлении существующей записи в таблице Inventory, первым делом потребуется решить, какие характеристики будет позволено изменять вызывающему коду: цвет автомобиля, его дружественное имя, модель или все перечисленное? Один из способов предоставления вызывающему коду полной гибкости заключается в определении метода, принимающего параметр типа string, который представляет любой оператор SQL, но в лучшем случае это сопряжено с риском.

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

public void UpdateCarPetName(int id, string newPetName)

{

  OpenConnection();

  // Получить идентификатор автомобиля для модификации дружественного имени.

  string sql = $"Update Inventory Set PetName = '{newPetName}'

                 Where Id = '{id}'";

  using (SqlCommand command = new SqlCommand(sql, _sqlConnection))

  {

    command.ExecuteNonQuery();

  }

  CloseConnection();

}

Работа с параметризированным и объектами команд

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

Для поддержки параметризированных запросов объекты команд ADO.NET содержат коллекцию индивидуальных объектов параметров. По умолчанию коллекция пуста, но в нее можно вставить любое количество объектов параметров, которые отображаются на параметры-заполнители в запросе SQL. Чтобы ассоциировать параметр внутри запроса SQL с членом коллекции параметров в объекте команды, параметр запроса SQL необходимо снабдить префиксом в виде символа @ (во всяком случае, когда применяется Microsoft SQL Server; не все СУБД поддерживают такую систему обозначений).

Указание параметров с использованием типа DbParameter

Перед построением параметризированного запроса вы должны ознакомиться с типом DbParameter (который является базовым классом для объекта параметра поставщика). Класс DbParameter поддерживает несколько свойств, которые позволяют конфигурировать имя, размер и тип параметра, а также другие характеристики, включая направление движения параметра. Некоторые основные свойства типа DbParameter описаны в табл. 21.6.

Давайте теперь посмотрим, как заполнять коллекцию совместимых с DBParameter объектов, содержащуюся в объекте команды, для чего переделаем методы InventoryDal для использования параметров.

Обновление метода GetCar()

В исходной реализации метода GetCar() при построении строки SQL для извлечения данных об автомобиле применяется интерполяция строк С#. Чтобы обновить метод GetCar(), создайте экземпляр SqlParameter с соответствующими значениями:

SqlParameter param = new SqlParameter

{

  ParameterName = "@carId",

  Value = id,

  SqlDbType = SqlDbType.Int,

  Direction = ParameterDirection.Input

}

Значение ParameterName должно совпадать с именем, используемым в запросе SQL (который будет модифицирован следующим), тип обязан соответствовать типу столбца базы данных, а направление зависит от того, применяется параметр для отправки данных в запрос (ParameterDirection.Input) или он предназначен для возвращения данных из запроса (ParameterDirection.Output). Параметры также могут определяться как InputOutput или ReturnValue (возвращаемое значение, например, из хранимой процедуры).

Модифицируйте строку SQL для использования имени параметра ("@carid") вместо интерполированной строки C# ("{id}"):

string sql =

  @"SELECT i.Id, i.Color, i.PetName,m.Name as Make

        FROM Inventory i

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

        WHERE i.Id = @CarId";

Последнее обновление связано с добавлением нового объекта параметра в коллекцию Parameters объекта команды:

command.Parameters.Add(param);

Обновление метода DeleteCar()

Аналогично в исходной реализации метода DeleteCar() применяется интерполяция строк С#. Чтобы модифицировать этот метод, создайте экземпляр SqlParameter с надлежащими значениями:

SqlParameter param = new SqlParameter

{

  ParameterName = "@carId",

  Value = id,

  SqlDbType = SqlDbType.Int,

  Direction = ParameterDirection.Input

};

Обновите строку SQL для использования имени параметра ("@ carId"):

string sql = "Delete from Inventory where Id = @carId";

В заключение добавьте новый объект параметра в коллекцию Parameters объекта команды:

command.Parameters.Add(param);

Обновление метода UpdateCarPetName()

Метод UpdateCarPetName() требует предоставления двух параметров: одного для Id автомобиля и еще одного для нового значения PetName. Первый параметр создается в точности как в предыдущих двух примерах (за исключением отличающегося имени переменной), а второй параметр обеспечивает отображение на тип NVarChar базы данных (тип поля PetName из таблицы Inventory). Обратите внимание на установку значения Size. Важно, чтобы этот размер совпадал с размером поля базы данных, что обеспечит отсутствие проблем при выполнении команды:

SqlParameter paramId = new SqlParameter

{

  ParameterName = "@carId",

  Value = id,

  SqlDbType = SqlDbType.Int,

  Direction = ParameterDirection.Input

};

SqlParameter paramName = new SqlParameter

{

  ParameterName = "@petName",

  Value = newPetName,

  SqlDbType = SqlDbType.NVarChar,

  Size = 50,

  Direction = ParameterDirection.Input

};

Модифицируйте строку SQL для применения параметров:

string sql = $"Update Inventory Set PetName = @petName Where Id = @carId";

Последнее обновление касается добавления новых параметров в коллекцию Parameters

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

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