DEV Community

Rohit Cdy
Rohit Cdy

Posted on • Edited on

Implementing Soft Delete With EF Core.

Soft Delete with EF Core.

What is soft delete?

  • Prevents permanent deletion of records.

  • Flag set on record, indicating "delete".

  • Allows for easy restoration and maintains data integrity.

How to implement:

  • Create Marker Interface.

Define a marker interface ISoftDelete to mark entities that support soft delete.

public interface ISoftDelete
{
    bool IsDeleted { get; set; }
    DateTime? DeleteOnUtc { get; set; }
}
Enter fullscreen mode Exit fullscreen mode
  • Implement Soft Delete Interceptor.

Create a class SoftDeleteInterceptor to handle soft deletes in EF Core.

public sealed class SoftDeleteInterceptor: SaveChangesInterceptor
{
    public override ValueTask<InterceptionResult<int>> SavingChangesAsync(
        DbContextEventData eventData,
        InterceptionResult<int> result,
        CancellationToken cancellationToken = default)
    {
        if (eventData.Context is null)
        {
            return base.SavingChangesAsync(eventData, result, cancellationToken);
        }

        IEnumerable<EntityEntry<ISoftDeletable>> entries =
            eventData.Context.ChangeTracker.Entries<ISoftDeletable>()
                .Where(e => e.State == EntityState.Deleted);

        foreach (EntityEntry<ISoftDeletable> softDeletable in entries)
        {
            softDeletable.State = EntityState.Modified;
            softDeletable.Entity.IsDeleted = true;
            softDeletable.Entity.DeletedOnUtc = DateTime.UtcNow;
        }

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

Enter fullscreen mode Exit fullscreen mode
  • Configure Application Context.

Configure EF Core to use the soft delete interceptor and global query filters.

public class ApplicationDbContext: DbContext
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    public DbSet<User> Users { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        // HasQueryFilter is used to filter soft-deleted data automatically.
        modelBuilder.Entity<User>().HasQueryFilter(r => !r.IsDeleted);

        modelBuilder.Entity<User>()
        .HasIndex(r=> r.IsDeleted)
        .HasFilter("IsDeleted=0");

        // This HasFilter method accepts the SQL filter for records that will be 
            included in the index.
        // You can also create a filtered index using SQL:
         /*
           Create index IX_Users_IsDeleted on User(IsDeleted) where IsDelete =0;
         */
    }
}

Enter fullscreen mode Exit fullscreen mode
  • Register SoftDeleteIntercepter with dependency injection.
services.AddSingleton<SoftDeleteInterceptor>();
services.AddDbContext<ApplicationDbContext>(
    sp, options)=>options
        .UseSqlServer(connectionString)
        .AddInterceptor(
               sp.GetRequiredService<SoftDeleteInterceptor>()));

Enter fullscreen mode Exit fullscreen mode
  • Example Entity.

Create an example entity Review implementing the soft delete marker interface.

public class User: ISoftDeletable
{
    public int Id { get; set; }
    public string UserName { get; set; }
    public bool IsDeleted { get; set; }
    public DateTime? DeletedOnUtc { get; set; }
}

Enter fullscreen mode Exit fullscreen mode

Benefits:

  • Flexibility in managing data.
  • Simplified queries with automatic exclusion of soft-deleted records.
  • Improved performance with filtered indexes.

Conclusion

  • Soft delete ensures data integrity and flexibility in managing records without compromising performance.

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay