繁体   English   中英

多租户实体过滤

[英]Multi-tenant entity filtration

我正在多租户应用程序中,根据CompanyID列,不同的公司有所不同。 数据库中还有一些通用的核心表,例如Settings ,对于所有公司都是相同的。 我有两个基本的持久化类: PersistentObjectCompanyPersistentObject 最后一个继承自第一个,并添加CompanyId属性。 我将直接在存储库中插入公司ID标准,如下所示:

public class EntityFrameworkRepository<T> : Repository<T>
    where T : PersistentObject
{
    private readonly DbSet<T> set;
    private readonly IApplicationContext applicationContext;
    private readonly IQueryable<T> queryable;

    public EntityFrameworkRepository(DbSet<T> set,
                                     IApplicationContext applicationContext)
    {
        this.set = set;
        this.applicationContext = applicationContext;

        if (typeof (CompanyPersistentObject).IsAssignableFrom(typeof(T)))
        {
            // TODO: Apply CompanyPersistentObject filter
            // using applicationContext.CompanyID
        }
    }
}

这是一个好方法还是您可以提出更好的解决方案?
如果是的话,如何在DbSet<T>中注入CompanyPersistentObject的条件,其中TPersistentObject并且没有CompanyId属性?

我几乎完全按照您在我的申请中的建议去做。 我发现最难以实现的方法是“全部”包装器。 我想返回一个IQueryable但是对实体的linq不支持强制转换为实体。 这个问题的答案在这里提供:

如何使用通用存储库模式按类型有条件地过滤IQueryable

实际上,我确实是使用Martin Eden建议的技术开始的,但是我按照您的建议将其重构为单个基本存储库,现在它变得更加简单和安全。

这是我的“查找”方法的样子:

    public virtual T Find(int id)
    {
        T e = Context.Set<T>().Find(id);

        var od = e as OrganisationDependent;
        if (od != null && od.OrganisationID != CurrentOrganisationID)
            return null;

        if (e == null)
            return null;

        return e;
    }

我建议您改用具有此行为的CompanyRepository类扩展EntityFrameworkRepository类。 然后,您可以将CompanyRepository的类型参数约束为仅扩展CompanyPersistentObject(或更好的是接口)的类。

例如:

public class EntityFrameworkRepository<T> : Repository<T>
    where T : PersistentObject
{
    private readonly DbSet<T> set;
    private readonly IApplicationContext applicationContext;
    private readonly IQueryable<T> queryable;

    public EntityFrameworkRepository(DbSet<T> set,
                                 IApplicationContext applicationContext)
    {
        this.set = set;
        this.applicationContext = applicationContext;
    }
}


public class CompanyRepository<T> : Repository<T>
    where T : PersistentObject, ICompany
{
    public CompanyRepository(DbSet<T> set,
                                 IApplicationContext applicationContext)
    {
        this.set = setFilteredById(set, applicationContext.CompanyId);    
    }
}

暂无
暂无

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

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