Ef核心摘要来自DbContext的HasQueryFilter

时间:2019-10-15 11:44:00

标签: entity-framework entity-framework-core

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

简单的例子,如

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));
    }
}

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

1 个答案:

答案 0 :(得分:0)

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

  

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

您正在引用导航属性LegalEntity

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

  

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

更新:

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