Filtering Out Soft-Deleted Records - EF Core

Overview

This article provides reusable code to create global query filters which will exclude soft-deleted rows from being returned from the database. This will work for any defined entity that (1) has an associated DbSet and (2) inherits from the IDeletable class - which has one field: bool IsDeleted.

Usage

In your OnModelCreating method, include the following line.

mb.ConfigureQueryFiltersForDeletables();

Reusable Code

internal interface IDeletable
{
    bool IsDeleted { get; set; }
}

public static void ConfigureQueryFiltersForDeletables(
    this ModelBuilder mb
    )
{
    /* TODO: Replace MyDataModel */
    var types = typeof(MyDataModel)
        .GetProperties()
        .Where(x => 
            x.PropertyType.IsGenericType
            && x.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>)
            )
        .Select(x => x.PropertyType.GenericTypeArguments.First())
        .Where(x =>
            x.GetInterfaces().Contains(typeof(IDeletable))
            )
        .Distinct()
        .ToList();

    foreach (var type in types)
    {
        dynamic dummyInstance = Activator.CreateInstance(type);
        ConfigureQueryFilterForDeletable(mb, dummyInstance);
    }
}

private static void ConfigureQueryFilterForDeletable<TEntity>(
    ModelBuilder mb,
    TEntity item
    )
    where TEntity : class, IDeletable
{
    mb.Entity<TEntity>().HasQueryFilter(a => !a.IsDeleted);
}