I'm using dotnet
6, and I want to make a global query filter in ef core to check my authentication ID dynamically, but the OnModelCreating
runs just once in the lifecycle of ASP.net
. Do you have any ideas how to do this?
This is my OnModelCreating method. DeletedAt type is DateTime? and my authentication ID is CompanyId. I get _companyId from the constructor and the type of it is long?. When a request is triggered, this ID fills, but my idea's problem is this method called at the startup of the project! At that time, the _companyId is null and never called again!
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ApplyQueryFilters<IDeletedAt>(x => x.DeletedAt == null);
modelBuilder.ApplyQueryFilters<IDeletedAtAndCompany>(x => x.DeletedAt == null && x.CompanyId == _companyId);
}
This is my ApplyQueryFilters method if you need:
public static void ApplyQueryFilters<T>(this ModelBuilder modelBuilder, Expression<Func<T, bool>> expression)
{
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
if (entityType.ClrType.GetInterface(typeof(T).Name) == null) continue;
var newParam = Expression.Parameter(entityType.ClrType);
var newBody = ReplacingExpressionVisitor
.Replace(expression.Parameters.Single(), newParam, expression.Body);
modelBuilder.Entity(entityType.ClrType).HasQueryFilter(Expression.Lambda(newBody, newParam));
}
}
I think I need a new idea to resolve this issue.
CodePudding user response:
OnModelCreating is cashed in first time, it's not running again I assume.
CodePudding user response:
Add the companyId to your Db Context then initialize it when you create the DbContext or when authenticate (you should have a DbContext peer session) :
public class ApplicationDbContext
{
...
public long? _companyId ;
}
in your OnModelCreating add this default filter (adapt it to your case) :
modelBuilder.Entity<YourEntity>().HasQueryFilter(b => EF.Property<string>(b, "companyId") == _companyId );
change the _companyId when needed.