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());
}
}