throw new CustomConcurrencyException(
"A concurrency error happened.", ex);
// Произошла ошибка параллелизма
}
catch (RetryLimitExceededException ex)
{
// Подлежит регистрации в журнале и надлежащей обработке.
throw new CustomRetryLimitExceededException(
"There is a problem with SQl Server.", ex);
// Возникла проблема c SQL Server
}
catch (DbUpdateException ex)
{
// Подлежит регистрации в журнале и надлежащей обработке.
throw new CustomDbUpdateException(
"An error occurred updating the database", ex);
// Произошла ошибка при обновлении базы данных
}
catch (Exception ex)
{
// Подлежит регистрации в журнале и надлежащей обработке.
throw new CustomException(
"An error occurred updating the database", ex);
// Произошла ошибка при обновлении базы данных
}
}
Обработка событий DbContext и ChangeTracker
Перейдите к конструктору класса
ApplicationDbContext
и добавьте три события
DbContext
, которые обсуждались в предыдущей главе:
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
<b> base.SavingChanges += (sender, args) =></b>
<b> {</b>
<b> Console.WriteLine($"Saving changes for {((ApplicationDbContext)</b>
sender)!.Database!.
GetConnectionString()}");
<b> };</b>
<b> base.SavedChanges += (sender, args) =></b>
<b> {</b>
<b> Console.WriteLine($"Saved {args!.EntitiesSavedCount} changes for</b>
<b> {((ApplicationDbContext)sender)!.Database!.GetConnectionString()}");</b>
<b> };</b>
<b> base.SaveChangesFailed += (sender, args) =></b>
<b> {</b>
<b> Console.WriteLine(</b>
<b> $"An exception occurred! {args.Exception.Message} entities");</b>
<b> };</b>
}
Затем добавьте обработчики для событий
StateChanged
и
Tracked
класса
ChangeTracker
:
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
...
<b> ChangeTracker.Tracked += ChangeTracker_Tracked;</b>
<b> ChangeTracker.StateChanged += ChangeTracker_StateChanged;</b>
}
Аргументы события
Tracked
содержат ссылку на сущность, которая инициировала событие, и указывают, было оно получено из запроса (загруженного из базы данных) или добавлено программно. Добавьте в класс
ApplicationDbContext
следующий обработчик событий:
private void ChangeTracker_Tracked(object? sender, EntityTrackedEventArgs e)
{
var source = (e.FromQuery) ? "Database" : "Code";
if (e.Entry.Entity is Car c)
{
Console.WriteLine($"Car entry {c.PetName} was added from {source}");
}
}
Событие
StateChanged
инициируется при изменении состояния сущности. Одно из применений этого события — аудит. Поместите в класс
ApplicationDbContext
приведенный ниже обработчик событий. Если свойство
NewState
сущности имеет значение
Unchanged
, тогда выполняется проверка свойства
OldState
для выяснения, сущность была добавлена или же модифицирована.
private void ChangeTracker_StateChanged(object? sender,
EntityStateChangedEventArgs e)
{
if (e.Entry.Entity is not Car c)
{
return;
}
var action = string.Empty;
Console.WriteLine(
$"Car {c.PetName}
was {e.OldState} before the state changed to
{e.NewState}");
switch (e.NewState)
{