Entity Framework Interceptors

Découvrez comment les intercepteurs d'Entity Framework vous permettent de monitorer et modifier automatiquement vos opérations de base de données, pour un code plus propre et une meilleure maintena...

Olivier Dupuy
30 juillet 2025

4

Vues

0

Commentaires

2

Min de lecture

Les intercepteurs d'Entity Framework Core représentent un outil puissant pour intercepter et modifier les opérations de base de données avant ou après leur exécution. Dans cet article, nous explorerons en détail comment utiliser les intercepteurs EF Core pour améliorer la traçabilité, la performance et la maintenance de vos applications .NET.

Comprendre les Intercepteurs Entity Framework

Les intercepteurs permettent d'injecter une logique personnalisée dans le pipeline d'exécution d'EF Core. Ils peuvent être utilisés pour :

  • Logger les requêtes SQL
  • Modifier les commandes avant leur exécution
  • Implémenter des stratégies de retry
  • Gérer des audits automatiques

Types d'Intercepteurs Disponibles

EF Core propose plusieurs types d'intercepteurs :


// 1. DbCommandInterceptor
public class LoggingInterceptor : DbCommandInterceptor
{
    public override InterceptionResult<DbDataReader> ReaderExecuting(
        DbCommand command, 
        CommandEventData eventData, 
        InterceptionResult<DbDataReader> result)
    {
        Log.Information($"Executing SQL: {command.CommandText}");
        return result;
    }
}

// 2. SaveChangesInterceptor public class AuditInterceptor : SaveChangesInterceptor { public override ValueTask<InterceptionResult<int>> SavingChangesAsync( DbContextEventData eventData, InterceptionResult<int> result, CancellationToken cancellationToken = default) { var entries = eventData.Context.ChangeTracker .Entries() .Where(e => e.State == EntityState.Modified);

foreach (var entry in entries) { entry.Property("LastModified").CurrentValue = DateTime.UtcNow; }

return base.SavingChangesAsync(eventData, result, cancellationToken); } }

Configuration des Intercepteurs

L'enregistrement des intercepteurs se fait lors de la configuration du DbContext :


public class ApplicationDbContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder
            .UseSqlServer(connectionString)
            .AddInterceptors(new LoggingInterceptor())
            .AddInterceptors(new AuditInterceptor());
    }
}

Cas d'Usage Pratiques

1. Audit Automatique


public class AuditableEntity
{
    public DateTime CreatedAt { get; set; }
    public string CreatedBy { get; set; }
    public DateTime? LastModified { get; set; }
    public string LastModifiedBy { get; set; }
}

public class AuditableInterceptor : SaveChangesInterceptor { private readonly ICurrentUserService _currentUserService;

public AuditableInterceptor(ICurrentUserService currentUserService) { _currentUserService = currentUserService; }

public override InterceptionResult<int> SavingChanges( DbContextEventData eventData, InterceptionResult<int> result) { UpdateEntities(eventData.Context); return result; }

private void UpdateEntities(DbContext context) { var entries = context.ChangeTracker.Entries<AuditableEntity>(); foreach (var entry in entries) { if (entry.State == EntityState.Added) { entry.Entity.CreatedAt = DateTime.UtcNow; entry.Entity.CreatedBy = _currentUserService.UserId; }

if (entry.State == EntityState.Modified) { entry.Entity.LastModified = DateTime.UtcNow; entry.Entity.LastModifiedBy = _currentUserService.UserId; } } } }

2. Gestion des Soft Deletes


public interface ISoftDeletable
{
    bool IsDeleted { get; set; }
    DateTime? DeletedAt { get; set; }
}

public class SoftDeleteInterceptor : SaveChangesInterceptor { public override InterceptionResult<int> SavingChanges( DbContextEventData eventData, InterceptionResult<int> result) { var entries = eventData.Context.ChangeTracker .Entries<ISoftDeletable>() .Where(e => e.State == EntityState.Deleted);

foreach (var entry in entries) { entry.State = EntityState.Modified; entry.Entity.IsDeleted = true; entry.Entity.DeletedAt = DateTime.UtcNow; }

return result; } }

Bonnes Pratiques

  • Gardez les intercepteurs légers et focalisés sur une seule responsabilité
  • Évitez les opérations bloquantes dans les intercepteurs
  • Utilisez la journalisation appropriée pour le debugging
  • Implémentez des timeouts appropriés

Tests des Intercepteurs


public class AuditInterceptorTests
{
    [Fact]
    public async Task ShouldSetAuditFieldsOnSave()
    {
        // Arrange
        var options = new DbContextOptionsBuilder<TestDbContext>()
            .UseInMemoryDatabase("TestDb")
            .AddInterceptors(new AuditableInterceptor(new MockCurrentUserService()))
            .Options;

// Act using (var context = new TestDbContext(options)) { var entity = new TestEntity { Name = "Test" }; context.TestEntities.Add(entity); await context.SaveChangesAsync();

// Assert Assert.NotNull(entity.CreatedAt); Assert.NotNull(entity.CreatedBy); } } }

Considérations de Performance

Pour optimiser les performances lors de l'utilisation des intercepteurs :

  • Utilisez des pools de connexions appropriés
  • Implémentez du caching si nécessaire
  • Évitez les requêtes supplémentaires dans les intercepteurs
  • Utilisez des profilers pour identifier les goulots d'étranglement

Conclusion

Les intercepteurs Entity Framework constituent un outil puissant pour étendre et personnaliser le comportement d'EF Core. En suivant les bonnes pratiques et en comprenant leurs cas d'usage appropriés, ils peuvent grandement améliorer la maintenabilité et la robustesse de vos applications .NET.

Points clés à retenir :

  • Les intercepteurs permettent d'injecter une logique personnalisée dans le pipeline EF Core
  • Ils sont particulièrement utiles pour l'audit, le logging et la gestion des soft deletes
  • La performance doit être surveillée lors de leur utilisation
  • Les tests sont essentiels pour garantir leur bon fonctionnement
Partager cet article
42
12

Commentaires (0)

Rejoignez la discussion

Connectez-vous pour partager votre avis et échanger avec la communauté

Première discussion

Soyez le premier à partager votre avis sur cet article !

À propos de l'auteur
Olivier Dupuy

Développeur passionné et contributeur actif de la communauté technique.

Profil
Articles similaires
API versioning strategies
02 août 2025 3
C# & .NET
Cryptographie post-quantique
02 août 2025 3
C# & .NET
Géolocalisation et cartes interactives
02 août 2025 3
C# & .NET
Navigation rapide
Commentaires (0)