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

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);
Похожее
Jul 16, 2021
Author: Edward Pollack
Monitoring SQL Server for performance is a critical part of a DBA’s job. In this article, Edward Pollack explains some of the SQL Server performance monitor data and how to collect it. Windows collects a wide array of useful metrics...
Jul 5
Author: David
The .NET Generic Host is a feature which sets up some convenient patterns for an application including those for dependency injection (DI), logging, and configuration. It was originally named Web Host and intended for Web scenarios like ASP.NET Core applications...
Aug 15, 2023
Whether you have an app with just a few users or millions of users per day, like Agoda, improving the user experience by optimizing application performance is always crucial. In the case of very high-traffic websites in the cloud, this...
Jan 25
Author: Dev·edium
A deep dive into Ahead-of-Time (AOT) compilation for optimized performance What is it? Traditionally, .NET languages like C# use Just-in-Time (JIT) compilation. In this process, the source code is initially compiled into Common Intermediate Language (CIL) code, a platform-agnostic code...
Написать сообщение
Тип
Почта
Имя
*Сообщение
RSS
Если вам понравился этот сайт и вы хотите меня поддержать, вы можете
Семь итераций наивности или как я полтора года свою дебютную игру писал
Soft skills: 18 самых важных навыков, которыми должен владеть каждый работник
Функции и хранимые процедуры в PostgreSQL: зачем нужны и как применять в реальных примерах
Как лучше проводить one-to-one со своими сотрудниками: 5 лайфхаков из личного опыта
Компиляция и запуск C# и Blazor внутри браузера
Вопросы с собеседований, которые означают не то, что вы думаете
Как мы столкнулись с версионированием и осознали, что вариант «просто проставить цифры» не работает
8 вещей, которых не должен бояться разработчик
Жестокая правда будней программиста: 8 наблюдений
Выйди и зайди правильно
LinkedIn: Sergey Drozdov
Boosty
Donate to support the project
GitHub account
GitHub profile