dotnet / efcore

EF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
https://docs.microsoft.com/ef/
MIT License
13.8k stars 3.2k forks source link

Adding support for multiple and named query filters #35104

Open bittola opened 1 week ago

bittola commented 1 week ago

Closes #8576

This PR adds support for defining multiple named global query filters on an entity. It follows pattern used for keyed services in ASP.NET Core dependency injection. It's backward compatible with the existing implementation where only single unnamed filter was possible.

Examples:

protected override void OnModelCreating(ModelBuilder modelBuilder)
    => modelBuilder.Entity<MyEntity>()
        .HasQueryFilter(x => !_ids.Contains(x.Id))
        .HasQueryFilter("NameFilter", x => x.Name.StartsWith("Name"))
        .HasQueryFilter(GlobalFilters.Active, x => !x.IsDeleted)
        .HasQueryFilter(GlobalFilters.Published, x => !x.IsDraft);

public enum GlobalFilters
{
    Active,
    Published
}

The example above shows the basic usage of the feature. As you can see we can use a value of any type as a filter key. In our example it was string and enum values. If the filter key is not defined as it is in HasQueryFilter(x => !_ids.Contains(x.Id)), string.Empty is used under the hood. It can be later used to disable that anonymous filter.

var result = context.Entities
    .IgnoreQueryFilters(GlobalFilters.Active, "NameFilter")
    .IgnoreQueryFilters(string.Empty)
    .ToList();

This example shows how to ignore specific query filters by using their keys. To simplify the use we can use an overload allowing us to specify filters keys as params array. Sequential use of the method adds new keys to the ignored list. Note, that the string.Empty key disables the anonymous filter from the previous example.

If we want to ignore all filters at once we can do it be calling IgnoreQueryFilters overload with no parameters:

var result = context.Entities
    .IgnoreQueryFilters()
    .ToList();
bittola commented 1 week ago

@dotnet-policy-service agree

bittola commented 10 hours ago

will anybody review this? @roji , @ajcvickers

roji commented 9 hours ago

@bittola apologies, but the team is currently still very busy dealing with the 9.0 release that came out recently - we'll hopefully be able to get some time and review soon.