Closed iAmBipinPaul closed 1 week ago
I have found the issue. I will detail of the issue here later.
I was getting all entity that implements ITenant
then looping through each of them and I was calling static method where I was passing currentTenantService
.
var tenantEntities = allEntities
.Where(e => typeof(ITenant).IsAssignableFrom(e.ClrType));
foreach (var entityType in tenantEntities)
{
builder.Entity(entityType.ClrType).Property("TenantId").IsRequired();
entityType.AddTenantQueryFilter(currentTenantService);
}
static extension metho for filter
public static class TenantFilterQueryExtension
{
public static void AddTenantQueryFilter(
this IMutableEntityType entityData, ICurrentTenantService currentTenantService)
{
var methodToCall = typeof(SoftDeleteQueryExtension)
.GetMethod(nameof(GetTenantFilter),
BindingFlags.NonPublic | BindingFlags.Static)!
.MakeGenericMethod(entityData.ClrType);
var filter = methodToCall.Invoke(null, new object[] { currentTenantService });
entityData.SetQueryFilter((LambdaExpression)filter!);
entityData.AddIndex(entityData.FindProperty(nameof(ITenant.TenantId))!);
}
private static LambdaExpression GetTenantFilter<TEntity>(CurrentTenantService currentTenantService)
where TEntity : class, ITenant
{
Expression<Func<TEntity, bool>> filter = x => x.TenantId == currentTenantService.GetCurrent().Id;
return filter;
}
}
when requesting was coming for that first time it was setting query filter with that tenant and it was stating their till, we restart the application
Sorry I was late to reply. I see you ran into the model cache.
The tenant query filter is implemented in MultiTenantDbContext
and its related extension methods in such a way to avoid this. Did these not work for your use case?
in other words you reimplemented the logic Finbuckle provides in its EFCore support but that’s ok if it works for you!
I was getting all entity that implements
ITenant
then looping through each of them and I was calling static method where I was passingcurrentTenantService
.var tenantEntities = allEntities .Where(e => typeof(ITenant).IsAssignableFrom(e.ClrType)); foreach (var entityType in tenantEntities) { builder.Entity(entityType.ClrType).Property("TenantId").IsRequired(); entityType.AddTenantQueryFilter(currentTenantService); }
static extension metho for filter
public static class TenantFilterQueryExtension { public static void AddTenantQueryFilter( this IMutableEntityType entityData, ICurrentTenantService currentTenantService) { var methodToCall = typeof(SoftDeleteQueryExtension) .GetMethod(nameof(GetTenantFilter), BindingFlags.NonPublic | BindingFlags.Static)! .MakeGenericMethod(entityData.ClrType); var filter = methodToCall.Invoke(null, new object[] { currentTenantService }); entityData.SetQueryFilter((LambdaExpression)filter!); entityData.AddIndex(entityData.FindProperty(nameof(ITenant.TenantId))!); } private static LambdaExpression GetTenantFilter<TEntity>(CurrentTenantService currentTenantService) where TEntity : class, ITenant { Expression<Func<TEntity, bool>> filter = x => x.TenantId == currentTenantService.GetCurrent().Id; return filter; } }
when requesting was coming for that first time it was setting query filter with that tenant and it was stating their till, we restart the application
Hi @AndrewTriesToCode np ta all
The other main db context I have does not inherit form MultiTenantDbContext
instead it just inherits form IdentityDbContext
.
I was not able to write code which will loop through each of the Entity that implements ITenant
and add Global query filter to filter result by current tenant so I have ended up writing one statement for each of the entity in main db context OnModelCreating
.
like this
builder.Entity<Product>(entity =>
{
entity.HasQueryFilter(c => c.IsDeleted == false && c.TenantId == tenantGetterService.Tenant.Id);
});
builder.Entity<EntityVersion>(entity =>
{
entity
.HasKey(p => new { p.EntityName, p.Timestamp });
entity.HasQueryFilter(c => c.TenantId == tenantGetterService.Tenant.Id);
});
Can you please point me to that part of code where I can take a look.
The tenant query filter is implemented in MultiTenantDbContext and its related extension methods in such a way to avoid this. Did these not work for your use case?
in other words you reimplemented the logic Finbuckle provides in its EFCore support but that’s ok if it works for you!
Hi @AndrewTriesToCode I'm new for this library and I've facing issue, where it for the first request it resolved the tenant correctly and after that all other request resolved to tenant which was resolved in first request. I'm not sure, what I'm doing wrong.
here are details of code follow
Tenant Db context
Service registration
Middleware
Service to get current Tenant
if I call end point with
abc.api.example.com
, with headerx-tenant-identifier:abc
=>abc
get resolvedxyz.api.example.com
, with headerx-tenant-identifier:xyz
it gets resolved toabc