TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.74K subscribers
Post #2142 2.45K
День 1769. #ЗаметкиНаПолях
Используем Перехватчики в EF Core

Перехватчики в EF Core позволяют перехватывать, изменять или подавлять операции EF Core.

Перехватчики регистрируются для каждого экземпляра DbContext при настройке контекста. Каждый перехватчик реализует интерфейс IInterceptor. Несколько распространённых производных интерфейсов включают
- IDbCommandInterceptor,
- IDbConnectionInterceptor,
- IDbTransactionInterceptor,
- ISaveChangesInterceptor.

Не обязательно реализовывать эти интерфейсы напрямую. Лучше использовать конкретные реализации и переопределить необходимые методы. Рассмотрим вариант использования перехватчиков с помощью самого распространённого перехватчика SaveChangesInterceptor, который добавляет поведение при сохранении изменений в базе данных.

Добавление записей аудита
Записи аудита изменений сущностей - ценная функция в некоторых приложениях. Вы записываете дополнительную информацию аудита каждый раз, когда объект создаётся или изменяется. Также это могут быть значения «до» и «после», в зависимости от ваших требований.
Например, создадим интерфейс IAuditable с датами создания и изменения объекта:
public interface IAuditable
{
DateTime Created { get; }
DateTime? Modified { get; }
}

Добавим UpdateInterceptor для записи значений аудита. Он использует ChangeTracker для поиска всех экземпляров IAuditable и устанавливает соответствующее значение свойства. Здесь мы используем метод SavingChangesAsync, который запускается до того, как изменения будут сохранены в БД.
internal sealed class UpdateInterceptor 
: SaveChangesInterceptor
{
public override
ValueTask<InterceptionResult<int>>
SavingChangesAsync(
DbContextEventData e,
InterceptionResult<int> result,
CancellationToken ct = default)
{
if (e.Context is not null)
UpdateEntities(e.Context);

return base
.SavingChangesAsync(e, result, ct);
}

private static void
UpdateEntities(DbContext ctx)
{
var now = DateTime.UtcNow;
var entities = ctx
.ChangeTracker
.Entries<IAuditable>()
.ToList();

foreach (var e in entities)
{
if (e.State == EntityState.Added)
e.Property(
nameof(IAuditable.Created)) = now;

if (e.State == EntityState.Modified)
e.Property(
nameof(IAuditable.Modified)) = now;
}
}
}

Эту реализацию можно легко расширить, включив в неё, например, информацию о текущем пользователе.

Зарегистрировать перехватчик можно следующим образом:
services.AddSingleton<UpdateInterceptor>();
services.AddDbContext<
IApplicationDbContext,
AppDbContext>(
(sp, opts) => opts
.UseSqlServer(connString)
.AddInterceptors(
sp.GetRequiredService<UpdateInterceptor>());


Источник: https://www.milanjovanovic.tech/blog/how-to-use-ef-core-interceptors
  • 👍 18
More from @netdeveloperdiary
  1. Sep 26, 2026День 2796. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Продолжение Начало Три…
  2. Sep 25, 2026День 2795. #ЗаметкиНаПолях #AI Рабочий процесс с Copilot для .NET. Начало Проблема с позиц…
  3. Sep 24, 2026День 2794. #Оффтоп #Здоровье Сегодня будет необычный пост. Завтра в Москве стартует конфер…
  4. Sep 23, 2026День 2793. #ЗаметкиНаПолях #SQL 10 Редких Возможностей SQL, Которые Стоит Знать Каждому. Ч…
  5. Sep 22, 2026День 2792. #ЗаметкиНаПолях #SQL 10 Редких Возможностей SQL, Которые Стоит Знать Каждому. Ч…
  6. Sep 21, 2026🔍Тестовое собеседование с Senior C# разработчиком уже завтра 22 сентября(уже завтра!) в 1…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →