我目前正在构建一个(非常直接的?)多租户网络应用程序原型,用户(存储在数据库 1 )可以注册到不同的租户(存储在数据库中每个租户(相同的数据库架构)。我认为这种架构适用于许多多租户解决方案。
可悲的是,我发现Entity Framework中不支持跨数据库关系(我认为它仍然是EF6的情况)。我提供了以下链接。
接下来的简短部分解释了我的问题,最终解释了我的问题。
我选择拥有单独的数据库;一个用户(1),一个用于每个租户及其客户特定信息。这样,当用户加入另一个租户时,用户不必创建新帐户(一个客户可以为不同的部门设置不同的域)。
我使用两个不同的DbContext
来实现这一点,一个用于用户,一个用于租户信息。在TenantContext
我定义DbSet
,其中包含引用User
实体(导航属性)的实体。
'per-tenant'背景:
public class CaseApplicationContext : DbContext, IDbContext
{
public DbSet<CaseType> CaseTypes { get; set; }
public DbSet<Case> Cases { get; set; }
// left out some irrelevant code
}
Case
实体:
[Table("Cases")]
public class Case : IEntity
{
public int Id { get; set; }
public User Owner { get; set; } // <== the navigation property
public string Title { get; set; }
public string Description { get; set; }
public Case()
{
Tasks = new List<Task>();
}
}
User
实体
[Table("Users")]
public class User : IEntity
{
public int Id { get; set; }
public string Name { get; set; }
public string EmailAddress { get; set; }
public string Password { get; set; }
}
这个User
实体也由Users
数据库包含在我的其他DbContext派生词中:
public class TenantApplicationContext : DbContext, IDbContext
{
public DbSet<Tenant> Tenants { get; set; }
public DbSet<User> Users { get; set; } // <== here it is again
// left out irrelevant code
}
预期:
我(我所有的愚蠢)想法会发生的事实是我实际上会创建一个跨数据库关系:
'per-tenant'数据库包含一个表'Cases'。此表包含具有“UserID”的行。 'UserID'指的是'用户'数据库。
实际
当我开始添加Case
时,我还在“per-tenant”数据库中创建另一个表“用户”。在我的'个案'表中,UserID
指的是同一个数据库中的表。
所以我开始谷歌搜索,发现这个功能根本不受支持。这让我想到,我是否应该将EF用于这样的应用程序?我应该转向NHibernate吗?
但我也无法想象微租户的实体框架会忽略多租户应用的巨大市场?所以我很可能正在做一些相当愚蠢的事情。
我认为主要问题是我的'数据库设计'。由于我是EF的新手并且在我学习的过程中学习,我可能会在几次错误的转弯(我的设计被破坏了吗?)。由于SO很好地代表了EF专家,我非常渴望了解我可以使用哪些替代方案来实现相同的目标(多租户,共享用户,可以在azure中部署)。我应该使用一个DbContext
还是能够部署具有共享Users
数据库的多租户Web应用程序吗?
我真的很感谢你的帮助!
学到的东西:
提前非常感谢你。我很乐意为你所有的努力给予奖励!
答案 0 :(得分:1)
我不太明白为什么你需要交叉数据库关系呢。假设您的应用程序可以与两个数据库(用户数据库和租户数据库)通信,它可以轻松地使用第一个数据库进行身份验证,然后使用“按名称”约定在租户数据库中查找相关用户。
例如,如果使用用户数据库对用户JOHN进行身份验证,则在租户数据库中搜索用户JOHN。
这将更容易实现并且仍然符合您的要求,用户与用户记录的密码和“卷影副本”一起存储在用户数据库中,但没有密码存储在租户数据库中,并且没有物理关系这两个。