Nic*_*ato 5 entity-framework multi-tenant
我正在开发一个多租户Web应用程序(堆栈:MVC 4 +实体框架4.3).我的要求非常简单:每个租户都有相同的UI和CodeBase.
在我的数据库中,我有一些带有TenantId字段的表(和其他表没有).
我已经建立了一个非常简单的通用存储库:
public class GenericRepository<TEntity> where TEntity : class
{
internal Database.CRMEntities context;
internal DbSet<TEntity> dbSet;
internal int tenantId;
public GenericRepository(Database.CRMEntities context)
{
this.context = context;
this.dbSet = context.Set<TEntity>();
this.tenantId = 1;
}
Run Code Online (Sandbox Code Playgroud)
我想用"get"方法来过滤我的tenantId.我的插入,更新和删除方法也应该约束适当的TenantId.
我的实体是自动生成的POCO类.
我考虑过这些解决方案:
1- GenericRepository应该实现一个定义TenantId的"ITenant"接口.问题是某些实体没有获得TenantId属性.另外,我真的不想修改我用来生成POCO对象的T4模板,以使它们实现我的界面
2-反射(但当然EF不能将其转换为SQL语句)
if (typeof(TEntity).GetProperty("TenantId") != null)
query = query.Where(x => (int) (x.GetType().GetProperty("TenantId").GetValue(x, null)) == tenantId);
Run Code Online (Sandbox Code Playgroud)
你会怎么做?如有必要,我愿意重新考虑我的架构.
谢谢,尼古拉
您可以执行反射检查,然后手动创建EF可以理解的表达式树.
例如:
int tenantId = 5;
var tenantIdInfo = typeof(TEntity).GetProperty("TenantId");
if (tenantIdInfo != null)
{
var entity = Expression.Parameter(typeof(TEntity), "it");
var predicate = (Expression<Func<TEntity, bool>>)Expression.Lambda(
Expression.Equal(
Expression.MakeMemberAccess(entity, tenantIdInfo),
Expression.Constant(tenantId, typeof(int))),
entity);
query = query.Where(predicate);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1755 次 |
| 最近记录: |