我正在尝试实现一个多租户应用程序,在该应用程序中我通过租户对象查询数据库,而不是直接脱离上下文。在我有这个之前:
public User GetUserByEmail(string email)
{
using (var db = CreateContext())
{
return db.Users.FirstOrDefault(u => u.Email.Equals(email, StringComparison.OrdinalIgnoreCase));
}
}
现在我有这个:
public User GetUserByEmail(string email)
{
using (var db = CreateContext())
{
return _tenant.Users.FirstOrDefault(u => u.Email.Equals(email, StringComparison.OrdinalIgnoreCase));
}
}
租户如下:
public class Tenant
{
public Tenant()
{
}
[Key]
[Required]
public int TenantId { get; set; }
public virtual DbSet<User> Users { get; set; }
// etc
}
我的用户模型具有以下内容:
public virtual List<Tenant> Tenants { get; set; }
在我的上下文配置中,我有以下内容:
modelBuilder.Entity<Tenant>()
.HasMany(e => e.Users)
.WithMany()
.Map(m =>
{
m.ToTable("UserTenantJoin");
m.MapLeftKey("TenantId");
m.MapRightKey("UserId");
});
但是我遇到了一个问题,即 DbSet 与上面的 ModelBuilder 不兼容 - 它让 HasMany 窒息,说不能从使用中推断出 DbSet 的使用。
我改用 ICollection 玩,但是在我的服务层中,所有对_tenant.Users.Include(stuff)
、 orFind()
和其他数据库查询的调用都中断了。
如果我使用 ICollection 会中断的服务方法示例:
public User GetUserWithInterestsAndAptitudes(string username)
{
using (var db = CreateContext())
{
return _tenant.Users. // can't use .Include on ICollection
Include(u => u.Relationships).
Include(u => u.Interests).
Include(u => u.Interests.Select(s => s.Subject)).
Include(u => u.Interests.Select(s => s.Aptitude)).
FirstOrDefault(s => s.Username.Equals(username, StringComparison.OrdinalIgnoreCase));
}
}
我希望有一个解决方案可以让我保持导航属性可查询,而无需重新构建我的服务层。
一种选择是我通过 将所有内容恢复为使用上下文db.Users
,然后为每个查询添加另一个条件.Where(u => u.TenantId == _tenant.TenantId)
- 但我试图避免这种情况。
在这里的任何帮助将不胜感激。