Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен
Книгу Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен читаем онлайн бесплатно полную версию! Чтобы начать читать не надо регистрации. Напомним, что читать онлайн вы можете не только на компьютере, но и на андроид (Android), iPhone и iPad. Приятного чтения!
Шрифт:
Интервал:
Закладка:
SqlDbType = SqlDbType.NVarChar,
Size = 50,
Direction = ParameterDirection.Input
};
SqlParameter parameterLastName = new SqlParameter
{
ParameterName = "@LastName",
Value = lName,
SqlDbType = SqlDbType.NVarChar,
Size = 50,
Direction = ParameterDirection.Input
};
cmdInsert.Parameters.Add(parameterId2);
cmdInsert.Parameters.Add(parameterFirstName);
cmdInsert.Parameters.Add(parameterLastName);
// Это будет получено из объекта подключения.
SqlTransaction tx = null;
try
{
tx = _sqlConnection.BeginTransaction();
// Включить команды в транзакцию.
cmdInsert.Transaction = tx;
cmdUpdate.Transaction = tx;
// Выполнить команды.
cmdInsert.ExecuteNonQuery();
cmdUpdate.ExecuteNonQuery();
// Эмулировать ошибку.
if (throwEx)
{
throw new Exception("Sorry! Database error! Tx failed...");
// Возникла ошибка, связанная с базой данных! Отказ транзакции...
}
// Зафиксировать транзакцию!
tx.Commit();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
// Любая ошибка приведет к откату транзакции.
// Использовать условную операцию для проверки на предмет null.
tx?.Rollback();
}
finally
{
CloseConnection();
}
}
Здесь используется входной параметр типа bool, который указывает, нужно ли генерировать произвольное исключение при попытке обработки проблемного клиента. Такой прием позволяет эмулировать непредвиденные обстоятельства, которые могут привести к неудачному завершению транзакции. Понятно, что это делается лишь в демонстрационных целях; настоящий метод транзакции не должен позволять вызывающему процессу нарушать работу логики по своему усмотрению!
Обратите внимание на применение двух объектов SqlCommand для представления каждого шага транзакции, которая будет запущена. После получения имени и фамилии клиента на основе входного параметра customerID с помощью метода BeginTransaction() объекта подключения можно получить допустимый объект SqlTransaction. Затем (что очень важно) потребуется привлечь к участию каждый объект команды, присвоив его свойству Transaction полученного объекта транзакции. Если этого не сделать, то логика вставки и обновления не будет находиться в транзакционном контексте.
После вызова метода ExecuteNonQuery() на каждой команде генерируется исключение, если (и только если) значение параметра bool равно true. В таком случае происходит откат всех ожидающих операций базы данных. Если исключение не было сгенерировано, тогда в результате вызова Commit() оба шага будут зафиксированы в таблицах базы данных.
Тестирование транзакции базы данных
Выберите одного из клиентов, добавленных в таблицу Customers (например, Dave Benner, Id = 1). Добавьте в Program.cs внутри проекта AutoLot.Client новый метод по имени FlagCustomer():
void FlagCustomer()
{
Console.WriteLine("***** Simple Transaction Example *****n");
// Простой способ позволить транзакции успешно завершиться или отказать.
bool throwEx = true;
Console.Write("Do you want to throw an exception (Y or N): ");
// Хотите ли вы сгенерировать исключение?
var userAnswer = Console.ReadLine();
if (string.IsNullOrEmpty(userAnswer) ||
userAnswer.Equals("N",StringComparison.OrdinalIgnoreCase))
{
throwEx = false;
}
var dal = new InventoryDal();
// Обработать клиента 1 - ввести идентификатор клиента,
// подлежащего перемещению.
dal.ProcessCreditRisk(throwEx, 1);
Console.WriteLine("Check CreditRisk table for results");
// Результаты ищите в таблице CreditRisk
Console.ReadLine();
}
Если вы запустите программу и укажете на необходимость генерации исключения, то обнаружите, что фамилия клиента в таблице Customers не изменилась, т.к. произошел откат всей транзакции. Однако если исключение не генерировалось, тогда окажется, что фамилия клиента в таблице Customers изменилась и была добавлена в таблицу CreditRisks.
Выполнение массового копирования с помощью ADO.NET
В случае, когда необходимо загрузить много записей в базу данных, показанные до сих пор методы будут довольно неэффективными. В SQL Server имеется средство, называемое массовым копированием, которое предназначено специально для таких сценариев, и в ADO.NET для него предусмотрена оболочка в виде класса SqlBulkCopy. В настоящем разделе главы объясняется, как выполнять массовое копирование с помощью ADO.NET.
Исследование класса SqlBulkCopy
Класс SqlBulkCopy имеет один метод, WriteToServer() (и его асинхронную версию WriteToServerAsync()), который обрабатывает список записей и помещает данные в базу более эффективно, чем последовательность операторов Insert, выполненная с помощью объектов команд. Метод WriteToServer() перегружен, чтобы принимать объект DataTable, объект DataReader или массив объектов DataRow. Придерживаясь тематики главы, мы собираемся использовать версию WriteToServer(), которая принимает DataReader, так что необходимо создать специальный класс чтения данных.
Создание специального класса чтения данных
Желательно, чтобы специальный класс чтения данных был обобщенным и содержал список моделей, которые нужно импортировать. Создайте в проекте AutoLot.DAL новую папку по имени BulkImport, a в ней — новый файл интерфейса IMyDataReader.cs, реализующего IDataReader, со следующим кодом:
using System.Collections.Generic;
using System.Data;
namespace AutoLot.Dal.BulkImport
{
public interface IMyDataReader<T> : IDataReader
{
List<T> Records { get; set; }
}
}
Далее реализуйте специальный класс чтения данных. Как вы уже видели, классы чтения данных содержат много частей, отвечающих за перемещение данных. Хорошая новость в том, что для SqlBulkCopy придется реализовать лишь несколько из них. Создайте новый файл класса по имени MyDataReader.cs и добавьте в него перечисленные ниже операторы using:
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
Сделайте класс открытым и запечатанным и обеспечьте реализацию классом интерфейса IMyDataReader. Добавьте конструктор для принятия записей и установки свойства:
public sealed class MyDataReader<T> : IMyDataReader<T>
{
public List<T> Records { get; set; }
public MyDataReader(List<T> records)
{
Records = records;
}
}
Предложите Visual Studio или Visual Studio Code самостоятельно реализовать все методы (либо скопировать их), что даст вам отправную точку для специального класса чтения данных. В рассматриваемом
Прочитали книгу? Предлагаем вам поделится своим отзывом от прочитанного(прослушанного)! Ваш отзыв будет полезен читателям, которые еще только собираются познакомиться с произведением.
Уважаемые читатели, слушатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.
- 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
- 2. Просьба отказаться от оскорблений, угроз и запугиваний.
- 3. Просьба отказаться от нецензурной лексики.
- 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.
Надеемся на Ваше понимание и благоразумие. С уважением, администратор knigkindom.ru.
Оставить комментарий
-
Гость Татьяна24 сентябрь 22:20 Как то не очень... Невеста по ошибке. Я не дам тебе развод - Майя Линн
-
Римма24 сентябрь 21:52 Почему главные героинитпкие идиотки? И сюжет не плохой, и написано хорошо. Но как героиня - так дура дурой.... Хозяйка маленького дома, или Любимая для дракона - Кира Рамис
-
Римма20 сентябрь 12:27 Много ненужных пояснений и отступлений. Весь сюжет теряет свою привлекательность. Героиня иногда так тупит, что читать не... Хозяйка приюта для перевертышей и полукровок - Елена Кутукова