我正在尝试在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上。
答案 0 :(得分:0)
来自https://docs.microsoft.com/en-us/ef/core/querying/filters
过滤器不能包含对导航属性的引用。
您正在引用导航属性LegalEntity
。
这可能会影响您以及您传递IEnumerable<IEntityAuthorization>
:
当前无法在上定义多个查询过滤器 同一实体-仅应用最后一个实体。但是,您可以 使用逻辑AND定义具有多个条件的单个过滤器 运算符(C#中的&&)。
更新:
那么我的猜测是,您需要直接引用MyDbContext
的字段/属性,而不是在另一个对象内。插入一个类/接口,该类/接口可以访问用于过滤的值,然后在OnModelCreating
方法的末尾配置过滤器。您可以遍历实体配置及其属性,以根据适用属性的存在来应用所需的过滤器。