Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ef core - multi tenancy using global filters

OnModelCreating is called once per db context. This is a problem since the tenant Id is set per request.

How do I re-configure the global filter everytime I create an new instance of the dbcontext?

If I can't use global filter, what is the alternative way?

Update:

I needed to provide a generic filter with an expression like e => e.TenantId == _tenantId. I am using the following expression:

var p = Expression.Parameter(type, "e");
Expression.Lambda(
    Expression.Equal(
        Expression.Property(p, tenantIdProperty.PropertyInfo),
        Expression.Constant(_tenantId))
    p);

Since this is run once, _tenantId is fixed. So even if I update it, the first value is captured in the linq expression.

So my question, what is the proper way to set the right side of that equality.

like image 625
herme 0 Avatar asked Sep 14 '26 22:09

herme 0


2 Answers

With EF.Core you can actually use the following filter and syntax

protected void OnModelCreating(ModelBuilder modelBuilder)
{
    var entityConfiguration = modelBuilder.Entity<MyTenantAwareEntity>();
    entityConfiguration.ToTable("my_table")
               .HasQueryFilter(e => EF.Property<string>(e, "TenantId") == _tenantProvider.GetTenant())
    [...]

The _tenantProvider is the class responsible to get your tenant, in your case from the HttpRequest, to do it you can use HttpContextAccessor.

like image 67
Norcino Avatar answered Sep 18 '26 02:09

Norcino


This is fixed with the following as the right expression

Expression.MakeMemberAccess(
    Expression.Constant(this, baseDbContextType),
    baseDbContextType.GetProperty("TenantId")

I use a base class for all my db contexts. GetProperty() works as is because TenantId is public property.

like image 43
herme 0 Avatar answered Sep 18 '26 02:09

herme 0



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!