Поиск  
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
Автор:
Источник:
Просмотров:
3014

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);
Похожее
May 13
Author: Dayanand Thombare
Creating functions that return multiple values in C# is an essential skill, especially when working with .NET Core applications. This article delves into various advanced strategies to return multiple values from functions, providing a deeper understanding of each approach with...
Jan 16, 2023
C# AngleSharp tutorial shows how to parse HTML in C# with AngleSharp library. The library can also parse SVG, MathML, or XML. AngleSharp GitHub: https://github.com/AngleSharp Document Object Model (DOM) is a standard tree structure, where each node contains one of...
Apr 3, 2023
Author: Hr. N Nikitins
Master the art of caching in .NET applications to improve performance and user experience. Caching is a powerful technique to improve application performance and response times. By temporarily storing the results of expensive operations or frequently accessed data, you can...
Oct 24, 2022
Author: Anton Shyrokykh
Entity Framework Core is recommended and the most popular tool for interacting with relational databases on ASP NET Core. It is powerful enough to cover most possible scenarios, but like any other tool, it has its limitations. Long time people...
Написать сообщение
Тип
Почта
Имя
*Сообщение