简体   繁体   English

在导航属性上使用EF Core HasQueryFilter

[英]Using EF Core HasQueryFilter on navigation properties

I'm trying to apply a filter to my queries for multi-tenancy but it doesn't allow me to apply the filter when the property is part of a navigation property: 我正在尝试将过滤器应用于我的多租户查询,但它不允许我在属性是导航属性的一部分时应用过滤器:

modelBuilder.Entity<Level>().HasQueryFilter(lvl => lvl.SchoolYear.TenantId == _tenantProvider.TenantId);

Here, Level is the property I want filtered but the property to use for filtering which is TenantId is is inside Level.SchoolYear. 这里,Level是我想要过滤的属性,但TenantId用于过滤的属性在Level.SchoolYear中。

If its a top-level property it works fine. 如果它是顶级房产,它可以正常工作。 How can I apply a global filter when the property I need for filtering is a navigation property? 当我需要过滤的属性是导航属性时,如何应用全局过滤器?

As said, these model level filters are not (yet) implemented for navigation properties. 如上所述,这些模型级过滤器尚未(导航)属性实现。 Which is sad, because people may not be aware of this restriction and count on it in a multi-tenant architecture. 这很难过,因为人们可能没有意识到这种限制并且在多租户架构中依赖它。 Everybody knows that making errors in a multi-tenant application may be the death of your company, so it's pretty vital to do this right. 每个人都知道在多租户应用程序中出错可能是贵公司的死亡,所以做到这一点非常重要。

Once you've chosen for tenant separation by TenantId (and not the safer schema-per-tenant or database-per-tenant), and knowing this current restriction in EF-core, you may want to build in a safeguard that at least you'll never mix up tenant data when saving changes. 一旦您选择TenantId进行租户分离(而不是每个租户更安全的模式或每个租户的数据库),并且知道EF-core中的当前限制,您可能希望建立一个至少是您的安全措施保存更改时,永远不会混淆租户数据。

This safeguard could be implemented by defining an interface: 可以通过定义接口来实现此安全措施:

public interface IHasTenantId
{
    int TenantId { get; }   
}

... to be implemented by each entity having a TenantId . ......由具有TenantId每个实体实施。

Then in an override of SaveChanges in the DbContext subclass there can be a check if all TenantId s in a change set are identical: 然后在DbContext子类中重写SaveChanges ,可以检查更改集中的所有TenantId是否相同:

public override int SaveChanges()
{
    var distinctTenantIdsCount = this.ChangeTracker.Entries<IHasTenantId>()
                                     .Select(e => e.Entity.TenantId)
                                     .Distinct().Count();
    if(distinctTenantIdsCount > 1)
    {
        // Throw an exception and handle it.
    }
    return base.SaveChanges();
}

You can't. 你不能。 It's a documented limitation of the current (as of EF Core 2.0.1) Global Query Filters implementation: 这是当前(从EF Core 2.0.1开始) 全局查询过滤器实现的文档限制:

Filters cannot contain references to navigation properties. 过滤器不能包含对导航属性的引用。

It's tracked by #8881: Allow to use navigations in model level entity filters enhancement request, but unfortunately has no concrete milestone assigned, which means we don't know if and when it will be fixed. 它由#8881跟踪:允许在模型级实体过滤器增强请求中使用导航 ,但遗憾的是没有分配具体的里程碑,这意味着我们不知道它是否以及何时将被修复。

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

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