Add a Global Query Filter to all Domain Entities in .NET
If you've ever wondered how you could automatically filter out soft-deleted entities without having to remember to exclude them manually, here's how.
Assuming you have a base entity that all your core entities inherit from like so:
public abstract class BaseEntity
{
public string Id { get; set; } = Guid.NewGuid().ToString();
public bool IsDeleted { get; set; } = false;
// …other properties
}
The old way of adding global query filters (there's an older way but I don't wanna go there)
builder.Entity<Address>().HasQueryFilter(m => !m.IsDeleted);
builder.Entity<Attribute>().HasQueryFilter(m => !m.IsDeleted);
builder.Entity<Brand>().HasQueryFilter(m => !m.IsDeleted);
Add the following to the OnModelCreating method of your ApplicationDbContext class
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Apply global query filter for soft delete
Expression<Func<BaseEntity, bool>> filterExpr = bm => !bm.IsDeleted;
var baseEntityTypes = builder.Model.GetEntityTypes()
.Where(entityType => entityType.ClrType.IsAssignableTo(typeof(BaseEntity)));
foreach (var baseEntityType in baseEntityTypes)
{
var parameter = Expression.Parameter(baseEntityType.ClrType);
var body = ReplacingExpressionVisitor.Replace(
filterExpr.Parameters[0], parameter, filterExpr.Body);
var lambdaExpression = Expression.Lambda(body, parameter);
baseEntityType.SetQueryFilter(lambdaExpression);
}
}
Now all your queries will automatically filter all soft-deleted entities.