我正在使用EF Core HasQueryFilter扩展方法,该方法位于OnModelCreating方法内部。
我正在使用服务将用户ID注入DbContext,然后将userId应用于查询过滤器。第一次执行OnModelCreating时,它可以按预期运行。但是,当我更改用户并将不同的userId传递给DbContext时,查询过滤器不会受到明显影响,因为这次未调用OnModelCreating。
该应用程序的一些背景知识:这是一个核心2.2 API项目,该项目使用JWT令牌对用户进行身份验证。我使用JWT填充用户声明并初始化注入的auth服务,因此对于API的每次调用,userId都可以不同,因此查询过滤器应在不同的userId上工作。
下面的示例代码:
public class SqlContext : DbContext
{
private readonly IAuthService _authService;
public SqlContext(DbContextOptions options, IAuthService authService) : base(options)
{
_authService = authService;
}
public DbSet<Device> Devices { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Device>().HasQueryFilter(p => !p.IsDeleted && p.ManufacturerId == _authService.ManufacturerId);
}
}
如何初始化DbContext。
services.AddDbContextPool<TContext>(o =>
o.UseSqlServer(configuration["Settings:SqlServer:DefaultConnection"],
b =>
{
b.MigrationsAssembly(configuration["Settings:SqlServer:MigrationAssembly"]);
b.CommandTimeout(60);
b.EnableRetryOnFailure(2);
})
.ConfigureWarnings(warnings =>
{
warnings.Throw(RelationalEventId.QueryClientEvaluationWarning);
}))
.AddTransient<TContext>();
答案 0 :(得分:0)
最后解决了。
由于过滤器正在工作,但是在首次请求后创建模型后,过滤器就没有更新。原因是EF正在缓存创建的模型。因此,我必须实现 IModelCacheKeyFactory 以便按照过滤器捕获不同的模型。
internal class DynamicModelCacheKeyFactory : IModelCacheKeyFactory
{
public object Create(DbContext context)
{
if (context is SqlContext dynamicContext)
{
return (context.GetType(), dynamicContext._roleCategory);
}
return context.GetType();
}
}
并将其附加到这样的上下文中。
protected override void OnConfiguring(DbContextOptionsBuilder builder)
{
base.OnConfiguring(builder);
builder.ReplaceService<IModelCacheKeyFactory, DynamicModelCacheKeyFactory>();
}