Search  
Always will be ready notify the world about expectations as easy as possible: job change page
Jul 1

Global query filters in EF Core

Global query filters in EF Core
Author:
Source:
Views:
1491

Say goodbye to the hassle of having to manually set a default filter for every query

EF Core provides a useful feature called Global Query Filters. It enables you to apply a filter to all queries sent to the database. Two examples of how this feature can be practically used are implementing soft delete and creating a multitenant database.

Building your own query filter

I will assume that you have already established the Database Context class for EF Core.

To add custom query filters, simply modify the OnModelCreating method in the DatabaseContext. Remember, setting query filters only affects specific tables within the database. To filter each table globally, we need to set a query filter on that particular entity.

For instance, the following piece of code creates a global query filter to ignore soft-deleted users:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    // Add a query filter to ignore all soft-deleted users
    modelBuilder.Entity<User>().HasQueryFilter(u => !u.IsDeleted);
}

Using extension methods

One thing I enjoy doing is developing an extension method that contains the soft delete logic and then implementing it as a query filter.

public static class ModelBuildExtensions
{
    public static void AddIsDeletedQueryFilter<T>(this ModelBuilder modelBuilder) where T : class, IBaseEntity
    {
        modelBuilder.Entity<T>().HasQueryFilter(u => !u.IsDeleted);
    }
}

With the use of this extension method, it is now possible to add soft delete global query filters in the following way:

// Add soft-delete global query filter for all of these entities
modelBuilder.AddIsDeletedQueryFilter<User>();
modelBuilder.AddIsDeletedQueryFilter<Image>();
modelBuilder.AddIsDeletedQueryFilter<Comment>();
modelBuilder.AddIsDeletedQueryFilter<Article>();

Ignoring global query filters

Having global query filters is great, but what if you need to view soft-deleted users specifically?

Fortunately, we can bypass global query filters by using the IgnoreQueryFilters() method through chaining.

var softDeletedUsers = _databaseContext.Users
  .IgnoreQueryFilters() // this line does the magic
  .Where(user => user.IsDeleted)
  .ToList();

Using multiple query filters

Unfortunately, EF Core does not allow you to define multiple query filters on the same entity.

// This won't work, as an entity can only have one query filter in EF Core
modelBuilder.Entity<User>()
  .HasQueryFilter(u => !u.Age < 18)
  .HasQueryFilter(u => !u.IsDeleted);

At the time of writing this, this is currently an open issue on the EF Core Github page: https://github.com/dotnet/efcore/issues/10275.

But, if your query filter is straightforward, you can combine them into one query filter.

// This will work, as it's only one query filter
modelBuilder.Entity<User>()
  .HasQueryFilter(u => !u.Age < 18 || !u.IsDeleted);
Similar
Feb 5, 2023
Memory leaks have long been programmer’s worst nightmare in .NET. When it comes to production servers, memory leaks are one of the most common and annoying issues. As we all know production servers must operate with the least amount of...
May 21
Author: Kostiantyn Bilous
Imagine a situation where you are working on an extensive financial application that processes thousands of transactions per minute. You discover that the system's performance has sharply declined at some point, and users begin to complain about delays. Upon analysis,...
Sep 14, 2023
Author: Mickvdv
In the world of modern software architecture, reliable communication between different components or microservices is crucial. This is where RabbitMQ, a queue based message broker, can play a vital role. RabbitMQ is a popular choice for implementing message queuing systems,...
Jan 11, 2023
Author: Nitesh Singhal
Database Setup with DbUp + Postgresql + Dapper in ASP.Net Core In this tutorial, we are going to explore how we can setup our database on startup when using Dapper for accessing database. When using Dapper, one of the key...
Send message
Email
Your name
*Message


© 1999–2024 WebDynamics
1980–... Sergey Drozdov
Area of interests: .NET Framework | .NET Core | C# | ASP.NET | Windows Forms | WPF | HTML5 | CSS3 | jQuery | AJAX | Angular | React | MS SQL Server | Transact-SQL | ADO.NET | Entity Framework | IIS | OOP | OOA | OOD | WCF | WPF | MSMQ | MVC | MVP | MVVM | Design Patterns | Enterprise Architecture | Scrum | Kanban