Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to configure multiple query filters on a given DbSet and disable them individually/specifically. #33432

Closed
jasonayerp opened this issue Mar 29, 2024 · 3 comments

Comments

@jasonayerp
Copy link

Feature Request

I would like to have the ability to be able to configure on a per DbSet basis, multiple query filters and be able to disable them individually. As opposed to the current all-or-none design, as I have some filters I would like to setup as permanent and some that could be disabled at runtime.

Motivation/Problem

When developing a multi-tenant database with a single instance with discriminator column (ex: TenantId) as recommended here, I would like to have other query filters that can be disabled at runtime without disabling a query filter that is required for multi-tenancy.

Consider the following configuration using the current latest version of EntityFramework Core

modelBuilder.Entity<CompanyEntity>().HasQueryFilter(x => x.TenantId == tenantId && x.IsActive);

With this example, if I wanted to retrieve records regardless of the IsActive value, I would have to disable the query filter which would also disable by always required multi-tenant query filter. The only alternative is to ensure that the Linq statement is always using the multi-tenant predicate. Not ideal as this could lead to bugs and data corruption between tenants.

var result = await context.Companies.IgnoreQueryFilters().ToListAsync(); // this would now get me all data across all tenants

Preferred Solution

The preferred solution involves:

  • Using a single database instance
  • Adding a discriminator column to all tables
  • Configuring multiple query filters (still per DbSet) but with a key

Consider the following proposal:

modelBuilder.Entity<CompanyEntity>().HasQueryFilter("Tenant", x => x.TenantId == tenantId).HasQueryFilter("ActiveOnly", x => x.IsActive);

This way I can ignore only the predicates I want:

var result = await context.Companies.IgnoreQueryFilter("ActiveOnly"); // now the data is restricted to the current multi-tenant

Assumptions

With the given solution a few design assumptions would need to be discussed

  • The inner list that tracks the predicates to key would either need to overwrite duplicates OR treat it as a hash and throw exceptions on duplicate insert
  • When IgnoreQueryFilter(string key) is called and no matching query filter is configured, then compose the LINQ query as if that query filter was not registered in the first place
  • If more than one query filter needs to be disabled then chained calls to IgnoreQueryFilter(string key) would be allowed.
@roji
Copy link
Member

roji commented Mar 30, 2024

Duplicate of #17347

@roji roji marked this as a duplicate of #17347 Mar 30, 2024
@roji
Copy link
Member

roji commented Mar 30, 2024

Duplicate of #10275

@roji roji marked this as a duplicate of #10275 Mar 30, 2024
@roji
Copy link
Member

roji commented Mar 30, 2024

@jasonayerp as far as I can tell, your requests are already tracked by the above two issues; other possible improvements to query filters are tracked by #21459.

I'll go ahead and close this, but if you think there's something not already covered by the other issues, please post back and we can reopen.

@roji roji closed this as not planned Won't fix, can't repro, duplicate, stale Mar 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants