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

Disable QueryFilter for Root Tenant Globally #922

Open
eluvitie opened this issue Dec 23, 2024 · 2 comments
Open

Disable QueryFilter for Root Tenant Globally #922

eluvitie opened this issue Dec 23, 2024 · 2 comments
Labels

Comments

@eluvitie
Copy link

eluvitie commented Dec 23, 2024

Hi there

In my web API I have a root tenant, which should be able to access all the data that the tenants have.

Here is some Information about the Project:

  • .NET 8 Web API
  • Postgresql
  • EF Core
  • Ardialis Specifications
  • Clean Architecture
  • Tenants Share the same Database
  • Finbuckle Multitenancy

Currently I set on each query the IgnoreGlobalQuery() and then set manaully the Filter for the SoftDelete Flag. This approach works if i only load one Entity, the problem is when i try to load child elements, because i'd have to set the SoftDelete Filter for each related Entity or else it displays all the deleted child elements.

So here is my question, is there a way to disable the global filter queries for the tenantId just for one Tenant (in my case the root Tenant)?

In my Optinion a nice way would be to set the filter (or disable) it when the DbContext for the Tenant gets initialized.

Here is my BaseDbContext:

public abstract class BaseDbContext : MultiTenantIdentityDbContext<ApplicationUser, ApplicationRole, string, IdentityUserClaim<string>, IdentityUserRole<string>, IdentityUserLogin<string>, ApplicationRoleClaim, IdentityUserToken<string>>
{
    protected readonly ICurrentUser _currentUser;
    private readonly ISerializerService _serializer;
    private readonly DatabaseSettings _dbSettings;
    private readonly IEventPublisher _events;

    protected BaseDbContext(ITenantInfo currentTenant, DbContextOptions options, ICurrentUser currentUser, ISerializerService serializer, IOptions<DatabaseSettings> dbSettings, IEventPublisher events)
        : base(currentTenant, options)
    {
        _currentUser = currentUser;
        _serializer = serializer;
        _dbSettings = dbSettings.Value;
        _events = events;
    }

   // this gets called once per startup
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // SoftDelete FilterQuery gets set for each Entitiy
        modelBuilder.AppendGlobalQueryFilter<ISoftDelete>(s => s.DeletedOn == null);

        base.OnModelCreating(modelBuilder);

        modelBuilder.ApplyConfigurationsFromAssembly(GetType().Assembly);
    }

    // this gets called for each Tenant
    // here would be a good place to disable to filter queries if the tenant is the root tenant.
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
      
       ......

    }

....

}

Thank for your help!

spent already a lot of time trying to figure out what the cleanest way is to achiev this.

@eluvitie
Copy link
Author

@AndrewTriesToCode Do you have an input what I could try or test to get this working?

@AndrewTriesToCode
Copy link
Contributor

hi @eluvitie sorry for the slow reply

You are hitting up against a design constraint within EFCore and the Finbuckle approach using global query filters. Here is something you can try that I've seen work well. Have a base DbContext class with your entities that your root tenant or admins use and derive your MultiTenant DbContext from it. Then the filters are only on instances of the subclass. This means your subclass can't inherit from MultiTenantDbContext but instead must implement IMultiTenantDbContext. [This section of the docs should help.] Then also you'll need to use the [fluent syntax] to designate which entities are multitenant in the derived class.

Let me know what you think!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants