Skip to content

Global Query Filters

Simon Hughes edited this page Mar 20, 2026 · 3 revisions

EF Core's global query filters allow you to define query predicates that are automatically applied to all queries for an entity type. Common use cases include soft-deletes and multi-tenancy.

Setup

Since the generated DbContext is sealed by default, you need to make it partial first.

In Database.tt:

Settings.DbContextClassModifiers = "public partial";

The generator then emits a call to OnModelCreatingPartial inside OnModelCreating:

// Generated code (do not edit)
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    // ... generated configuration ...
    OnModelCreatingPartial(modelBuilder);
}

partial void OnModelCreatingPartial(ModelBuilder modelBuilder);

Implementing Filters

Create a new file (e.g., MyDbContext.Filters.cs) with your partial class implementation. This file is not overwritten by the generator.

// MyDbContext.Filters.cs — hand-written, not generated
namespace MyProject.Data;

public partial class MyDbContext
{
    partial void OnModelCreatingPartial(ModelBuilder modelBuilder)
    {
        // Soft-delete filter: automatically exclude deleted records
        modelBuilder.Entity<Order>().HasQueryFilter(p => !p.IsDeleted);

        // Multi-tenant filter: only return records for the current tenant
        modelBuilder.Entity<Customer>().HasQueryFilter(c => c.TenantId == _currentTenantId);

        // Combine filters
        modelBuilder.Entity<Product>().HasQueryFilter(p => p.IsActive && !p.IsDeleted);
    }

    // Inject tenant context via constructor or property
    private readonly int _currentTenantId;
}

Disabling Filters Per Query

Global filters can be disabled for individual queries using .IgnoreQueryFilters():

// Include soft-deleted records for an admin view
var allOrders = dbContext.Orders.IgnoreQueryFilters().ToList();

Clone this wiki locally