繁体   English   中英

EF Core HasQueryFilter仅适用于过滤器表达式中的第一个值

[英]EF Core HasQueryFilter works for only the first value in filter expression

我正在使用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>();

终于解决了。

由于过滤器正在工作,但是在首次请求后创建模型后就不会更新。 原因是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>();
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM