Interceptors в EntityFramework Core или EF Core Перехватчики
Полезности | создано: 17.08.2024 | опубликовано: 16.03.2025 | обновлено: 04.09.2025 | просмотров: 687
Перехватчики Entity Framework Core (EF Core) позволяют перехватывать, изменять и (или) подавлять операции EF Core. Сюда входят низкоуровневые операции с базой данных, такие как выполнение команды, а также операции более высокого уровня, такие как вызовы SaveChanges.
Описание
Entity Framework Core (EF Core) — это мощное и гибкое объектно-реляционное сопоставление (ORM) для разработчиков .NET. Помимо своих функций, перехватчики предоставляют механизм подключения к конвейеру EF Core, позволяя разработчикам проверять, изменять или дополнять операции EF Core. В этом руководстве объясняются перехватчики, как они работают и их практическое применение с примерами.
Типы перехватчиков Interceptors
EF Core предоставляет несколько встроенных интерфейсов для определения перехватчиков:
- IDbCommandInterceptor: Для выполнения команд базы данных.
- ISaveChangesInterceptor: Для перехвата операций SaveChanges.
- IQueryExpressionInterceptor: для перехвата выражений запроса LINQ.
- IConnectionInterceptor: для операций подключения к базе данных.
- ITransactionInterceptor: Для перехвата операций, связанных с транзакциями.
Примеры
Это один из возможных примеров использования Interceptor при реализации SoftDelete. То есть, когда сущность не удаляется реально из БД, а помечается специальным образом, чтобы при выборке обычных сущностей удаленные был исключены.
public class SoftDeleteInterceptor : ISaveChangesInterceptor
{
    public override int SavingChanges(DbContextEventData eventData, InterceptionResult<int> result)
    {
        var context = eventData.Context;
        if (context == null) return base.SavingChanges(eventData, result);
        foreach (var entry in context.ChangeTracker.Entries())
        {
            // Handle entities with IsDeleted property
            if (entry.Entity is ISoftDeletable softDeletableEntity && entry.State == EntityState.Deleted)
            {
                entry.State = EntityState.Modified;
                softDeletableEntity.IsDeleted = true;
                // Update related entities if required for complex relationships
                if (entry.Entity is ITenantEntity tenantEntity)
                {
                    HandleTenantSpecificLogic(context, tenantEntity);
                }
            }
        }
        return base.SavingChanges(eventData, result);
    }
    private void HandleTenantSpecificLogic(DbContext context, ITenantEntity tenantEntity)
    {
        // Example: Ensure related tenant-specific records are soft-deleted or flagged appropriately
        var relatedEntities = context.ChangeTracker.Entries()
            .Where(e => e.Entity is IRelatedEntity && ((IRelatedEntity)e.Entity).TenantId == tenantEntity.TenantId);
        foreach (var relatedEntity in relatedEntities)
        {
            if (relatedEntity.State == EntityState.Deleted)
            {
                relatedEntity.State = EntityState.Modified;
                ((IRelatedEntity)relatedEntity.Entity).IsDeleted = true;
            }
        }
    }
}
Видео
Ссылки
Мои видео
Boosty.to | YouTube | Yandex.Дзен | RuTube | VK Video
