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>
(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})
<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)
{