entity-framework - 来自 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 上。
解决方案
来自https://docs.microsoft.com/en-us/ef/core/querying/filters
过滤器不能包含对导航属性的引用。
您正在引用导航属性LegalEntity
。
这可能会影响您以及您传入的IEnumerable<IEntityAuthorization>
:
当前无法在同一实体上定义多个查询过滤器 - 只会应用最后一个。但是,您可以使用逻辑 AND 运算符(C# 中的 &&)定义具有多个条件的单个过滤器。
更新:
我的猜测是您需要直接引用字段/属性,MyDbContext
而不是在另一个对象中。注入一个类/接口,该类/接口可以访问要过滤的值,然后在方法末尾配置过滤器OnModelCreating
。您可以对实体配置及其属性进行交互,以根据适用属性的存在应用所需的过滤器。
推荐阅读
- python - 从网络中提取评级
- android - 将 TextView 与另一个布局中的 ImageView 对齐
- javascript - 给定 y 获取 0 到 y 之间的所有数字
- github - 如何在“您必须重新授权 OAuth 应用程序`GitHub for VSCode`”后再次获得功能
- bootstrap-4 - Bootstrap 将元素添加到行
- dask - Dask read_sql_table 创建了一个附加列
- php - 如何在 Codeigniter 中使用 regex_match 在表单验证中验证多个日期格式
- nginx - 多个网站的 Nginx 配置、SSL、Google 索引问题
- node.js - 如何获取登录用户?req.user 未定义
- angular - Ionic6 选项卡不显示选项卡中的内容,但在 DOM 中显示