首页 > 解决方案 > 来自 DbContext 的 Ef 核心抽象 HasQueryFilter

问题描述

我正在尝试在 DbContext 之上构建一些通用的授权内容,以便我的开发人员不需要关心 repos/domain 中的授权。

简单的例子,如

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>().Property<string>("TenantId").HasField("_tenantId");

    // Configure entity filters
    modelBuilder.Entity<Blog>().HasQueryFilter(b => EF.Property<string>(b, "TenantId") == _tenantId);
    modelBuilder.Entity<Post>().HasQueryFilter(p => !p.IsDeleted);
}

哪个是 MS 示例有效。_tenantId 将用于创建表达式,并且对于 DbContext 的每个实例,它将使用正确的 _tenantId 值。

但是我不希望我们所有的授权都从我们的数据库上下文中配置,我想注入它。就像是

public class AgreementAuthorization : IEntityAuthorization
{
    private readonly string _legalEntityNumber;

    public AgreementAuthorization(IAuthScope scope)
    {
        _legalEntityNumber = scope.LegalEntityNumber;
    }

    public void Build(ModelBuilder builder)
    {
        builder
            .Entity<Agreement>()
            .HasQueryFilter(a => _legalEntityNumber == null || a.LegalEntity.Number == _legalEntityNumber);
    }
}

public class MyDbContext : DbContext 
{
   private IEnumerable<IEntityAuthorization> _entityAuthorization;

   MyDbContext(IEnumerable<IEntityAuthorization> entityAuthorization) 
   {
      _entityAuthorization = entityAuthorization;
   }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {                                
        builder.ApplyConfigurationsFromAssembly(typeof(MyDbContext).Assembly);

        _entityAuthorization.ForEach(a => a.Build(builder));
    }
}

这不起作用,查询将每次都针对 null 进行测试并通过。如果我将代码直接移动到 DbContext 它将起作用。含义 _entityAuthorization 直接位于 DbContext 上。

标签: entity-frameworkentity-framework-core

解决方案


来自https://docs.microsoft.com/en-us/ef/core/querying/filters

过滤器不能包含对导航属性的引用。

您正在引用导航属性LegalEntity

这可能会影响您以及您传入的IEnumerable<IEntityAuthorization>

当前无法在同一实体上定义多个查询过滤器 - 只会应用最后一个。但是,您可以使用逻辑 AND 运算符(C# 中的 &&)定义具有多个条件的单个过滤器。

更新:

我的猜测是您需要直接引用字段/属性,MyDbContext而不是在另一个对象中。注入一个类/接口,该类/接口可以访问要过滤的值,然后在方法末尾配置过滤器OnModelCreating。您可以对实体配置及其属性进行交互,以根据适用属性的存在应用所需的过滤器。


推荐阅读