EF Core: Easily detect slow running queries, and modify hard deletes
Implementing a Performance Interceptor
using Microsoft.EntityFrameworkCore.Diagnostics; using System.Diagnostics; public class PerformanceInterceptor : DbCommandInterceptor { private const long QuerySlowThreshold = 100; // milliseconds public override InterceptionResult<DbDataReader> ReaderExecuting( DbCommand command, CommandEventData eventData, InterceptionResult<DbDataReader> result) { Stopwatch stopwatch = Stopwatch.StartNew(); var originalResult = base.ReaderExecuting(command, eventData, result); stopwatch.Stop(); if (stopwatch.ElapsedMilliseconds > QuerySlowThreshold) { Console.WriteLine($"Slow Query Detected: {command.CommandText}"); } return originalResult; } }
Implementing Soft Deletes
public class MyEntity { public Guid Id { get; set; } public bool IsDeleted { get; set; } // Other properties... } public class SoftDeleteInterceptor : SaveChangesInterceptor { public override InterceptionResult<int> SavingChanges( DbContextEventData eventData, InterceptionResult<int> result) { foreach (var entry in eventData.Context.ChangeTracker.Entries()) { if (entry.State == EntityState.Deleted && entry.Entity is MyEntity entity) { entity.IsDeleted = true; entry.State = EntityState.Modified; } } return base.SavingChanges(eventData, result); } }
Register the interceptor with your DbContext.
using Microsoft.EntityFrameworkCore; public class SampleDbContext : DbContext { public DbSet<MyEntity> SampleEntities { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer("Your_Connection_String"); // Registering the PerformanceInterceptor optionsBuilder.AddInterceptors(new PerformanceInterceptor()); // Registering the SoftDeleteInterceptor optionsBuilder.AddInterceptors(new SoftDeleteInterceptor()); } }