Свойства виртуальной навигации и мультитенантность
У меня есть стандартDbContext
с кодом, подобным следующему:
public DbSet<Interest> Interests { get; set; }
public DbSet<User> Users { get; set; }
Недавно я реализовал многопользовательский режим, создавTenantContext
который содержит следующее:
private readonly DbContext _dbContext;
private readonly Tenant _tenant;
public TenantContext(Tenant tenant)
: base("name=DefaultConnection") {
this._tenant = tenant;
this._dbContext = new DbContext();
}
public IQueryable<User> Users { get { return FilterTenant(_dbContext.Users); } }
public IQueryable<Interest> Interests { get { return FilterTenant(_dbContext.Interests); } }
private IQueryable<T> FilterTenant<T>(IQueryable<T> values) where T : class, ITenantData
{
return values.Where(x => x.TenantId == _tenant.TenantId);
}
Пока что это работает отлично. Всякий раз, когда какой-либо из моих сервисов создает новый TenantContext, все запросыпрямо из этого контекста фильтруются через этоFilterTenant
метод, который гарантирует, что я возвращаю только связанные с арендатором объекты.
Проблема, с которой я сталкиваюсь, заключается в том, что я использую свойства навигации, которые не учитывают это:
using (var db = CreateContext()) // new TenantContext
{
return db.Users.
Include(u => u.Interests).FirstOrDefault(s => s.UserId == userId);
}
Этот запрос поднимает специфичный для арендатораUsers
, но тогдаInclude()
заявление тянет вInterests
только для этого пользователя - но для всех арендаторов. Поэтому, если у пользователя есть Интересы между несколькими Арендаторами, я получаю все Интересы пользователя с помощью вышеуказанного запроса.
Моя модель пользователя имеет следующее:
public int UserId { get; set; }
public int TenantId { get; set; }
public virtual ICollection<Interest> Interests { get; set; }
Можно ли как-то изменить эти свойства навигации для выполнения запросов, специфичных для арендатора? Или я должен пойти и вырвать все свойства навигации в пользу рукописного кода?
Второй вариант пугает меня, потому что многие запросы имеют вложенные Включения. Любой вклад здесь будет фантастическим.