EF Core Global Query Filters: A Complete Guide

Leader posted 2 min read

Entity Framework Core (EF Core) Global Query Filters allow you to apply filters to queries at the model level so that they automatically apply to all queries involving a specific entity.

This is particularly useful for scenarios like soft deletes, multi-tenancy, and user-based data filtering.

What is a Global Query Filter?

A global filter is a LINQ predicate that applies automatically to all queries on a specific entity type.

This means that any time you query the database, EF Core applies the filter implicitly, reducing the need for adding Where clauses manually.

Use Cases

  • Soft Deletes – Automatically filter out entities where IsDeleted =
    true.

  • Multi-Tenancy – Ensure that a tenant only accesses their own data.

  • User-Based Filtering – Restrict users to see only their own records.

How to Define a Global Query Filter

Global filters are defined in the OnModelCreating method inside the DbContext class using the HasQueryFilter method.

Example : Soft Delete Implementation ..

public class BaseEntity
{
    public bool IsDeleted { get; set; }
}

public class Product : BaseEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class AppDbContext : DbContext
{
    public DbSet<Product> Products { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Product>()
            .HasQueryFilter(p => !p.IsDeleted);
    }
}

Now, every query on Products automatically filters out records where IsDeleted = true.

Querying Products

var products = context.Products.ToList(); // Implicitly applies "WHERE IsDeleted = 0"

Bypassing the Global Filter

You can explicitly disable the filter using .IgnoreQueryFilters().

var allProducts = context.Products.IgnoreQueryFilters().ToList();

Applying Filters Dynamically (Multi-Tenancy Example)

public class AppDbContext : DbContext
{
    private readonly int _tenantId;

    public AppDbContext(DbContextOptions<AppDbContext> options, ITenantProvider tenantProvider)
        : base(options)
    {
        _tenantId = tenantProvider.GetTenantId();
    }

    public DbSet<Order> Orders { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Order>()
            .HasQueryFilter(o => o.TenantId == _tenantId);
    }
}

Now, EF Core automatically filters records based on _tenantId.

Limitations and Considerations

  • Filters do not apply to raw SQL queries (FromSqlRaw).

  • Navigation properties respect global filters (e.g., if Order has OrderDetails, the filter applies to them too).

  • Ensure filters do not cause unexpected performance issues on large datasets.

  • You can define multiple query filters per entity.

Combining Multiple Filters

modelBuilder.Entity<Product>()
    .HasQueryFilter(p => !p.IsDeleted)
    .HasQueryFilter(p => p.Status == "Active");

This results in:

SELECT * FROM Products WHERE IsDeleted = 0 AND Status = 'Active'

Disabling All Global Filters

You can disable all filters for a specific context query using:

context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;

or

var allOrders = context.Orders.IgnoreQueryFilters().ToList();

Conclusion
EF Core’s Global Query Filters help enforce consistent rules across queries without adding redundant Where clauses. They are a powerful feature for soft deletes, multi-tenancy, and user-based access control. However, they should be used carefully, considering potential performance impacts.

Source Code

You can find the complete source code for this tutorial at:
GitHub Repository

Here are some useful references to learn more about EF Core Global Query Filters and Soft Delete:

Official EF Core Documentation
Global Query Filters
https://learn.microsoft.com/en-us/ef/core/querying/filters

Entity Framework Core SQLite Provider
https://learn.microsoft.com/en-us/ef/core/providers/sqlite/

Managing Data with EF Core
https://learn.microsoft.com/en-us/ef/core/

Community Articles & Tutorials
EF Core: Global Query Filters for Soft Deletes
https://www.thinktecture.com/en/entity-framework-core/global-query-filters/

Implementing Soft Delete in EF Core
https://medium.com/swlh/soft-delete-in-entity-framework-core-6c6b7a9784c7

Using SQLite with EF Core in Console Applications
https://code-maze.com/using-sqlite-with-entity-framework-core/

If you read this far, tweet to the author to show them you care. Tweet a Thanks
0 votes
0 votes

More Posts

EF Core Bulk Updates and Deletes: Performance vs Change Tracking

Spyros - Mar 24

EF Core: Lazy Loading, Eager Loading, and Loading Data on Demand

Spyros - Mar 6

Optimistic vs. Pessimistic Concurrency in EF Core (with Table Hints)

Spyros - Mar 31

How to Bind a MudSelect from an External Source in Blazor Using MudBlazor

Spyros - Apr 10

Supercharging EF Core Specifications with EF.CompileQuery

Spyros - Aug 5
chevron_left