我正在开发多租户应用程序,其中不同的公司在CompanyID
列之间有所不同。数据库中还有一些共同的核心表,如Settings
,所有公司都是一样的。我有两个基本持久类:PersistentObject
和CompanyPersistentObject
。最后一个继承自第一个并添加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
}
}
}
这是一种好方法,还是可以提出更好的解决方案?
如果是这样,如何在CompanyPersistentObject
DbSet<T>
T
PersistentObject
并且没有CompanyId
属性的情况下注入{{1}}的条件?
答案 0 :(得分:1)
我几乎完全按照你的申请提出的建议。我发现最棘手的方法是“All”包装器。我想返回IQueryable
但是linq到实体不支持转换为实体。这个问题的答案在这里提供:
How to conditionally filter IQueryable by type using generic repository pattern
我确实开始使用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;
}
答案 1 :(得分:0)
我建议您使用具有此行为的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);
}
}