4

我正在使用 EF Core HasQueryFilter 扩展方法,它位于 OnModelCreating 方法中。

我正在使用服务将用户 ID 注入 DbContext,然后将用户 ID 应用于查询过滤器。第一次执行 OnModelCreating 时,它可以正常工作。但是当我更改用户并将不同的 userId 传递给 DbContext 时,查询过滤器不会受到明显影响,因为这次没有调用 OnModelCreating。

应用程序的一点背景:它是一个核心 2.2 API 项目,它使用 JWT 令牌对用户进行身份验证。我使用 JWT 填充用户声明并初始化注入的身份验证服务,因此对于 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>();
4

1 回答 1

3

终于解决了。

由于过滤器正在工作,但在第一次请求后创建模型后它没有得到更新。原因是 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>();
    }
于 2019-02-25T08:55:22.310 回答