在导航属性上使用EF Core HasQueryFilter [英] Using EF Core HasQueryFilter on navigation properties

查看:109
本文介绍了在导航属性上使用EF Core HasQueryFilter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试对多租户查询应用过滤器,但是当该属性是导航属性的一部分时,它不允许我应用该过滤器:

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

这里,Level是我要过滤的属性,但TenantId用于过滤的属性位于Level.SchoolYear中.

Here, Level is the property I want filtered but the property to use for filtering which is TenantId is is inside 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.

一旦您选择了通过 TenantId 进行租户分隔(而不是更安全的每租户架构或每租户数据库),并且知道EF核心中的当前限制,您可能希望建立一种保护措施,至少在保存更改时永远不会混淆租户数据.

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.

可以通过定义接口来实现此保护措施:

This safeguard could be implemented by defining an interface:

public interface IHasTenantId
{
    int TenantId { get; }   
}

...由具有 TenantId 的每个实体实施.

... to be implemented by each entity having a TenantId.

然后在 DbContext 子类中的 SaveChanges 的替代中,可以检查更改集中的所有 TenantId 是否相同:

Then in an override of SaveChanges in the DbContext subclass there can be a check if all TenantIds in a change set are identical:

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

这篇关于在导航属性上使用EF Core HasQueryFilter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆