2

概括

我目前正在原型设计一个(非常简单的?)多租户 Web 应用程序,其中用户(存储在数据库1中)可以注册到不同的租户(存储在每个租户的数据库中(相同的数据库模式)。我认为的架构适用于很多多租户解决方案。

遗憾的是,我发现 Entity Framework 不支持跨数据库关系(我认为 EF6 仍然是这种情况)。我提供了下面的链接。

接下来的简短部分解释了我的问题,最终解释了我的问题。

设计背后的理性

我选择拥有单独的数据库;一份用于用户 (1),一份用于每个租户及其客户特定信息。这样,用户在加入另一个租户时不必创建新帐户(一个客户可以为不同的部门拥有不同的域)。

它是如何实施的

我使用两个不同DbContext的 s 来实现这一点,一个用于用户,一个用于租户信息。在TenantContextI define DbSets 中,它包含引用User实体(导航属性)的实体。

“每个租户”上下文:

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
}

现在,出了什么问题?

预期的:

我(愚蠢地)认为会发生的是我实际上会创建一个跨数据库关系:

“每租户”数据库包含一个表“案例”。此表包含具有“用户 ID”的行。“用户 ID”指的是“用户”数据库。

实际的:

当我开始添加Cases 时,我还在我的“每个租户”数据库中创建另一个表“用户”。在我的“案例”表中,UserID指的是同一数据库中的表。

EF 中不存在跨数据库关系

所以我开始搜索,发现这个功能根本不支持。这让我想,我什至应该将 EF 用于这样的应用程序吗?我应该改用 NHibernate 吗?

但我也无法想象巨大市场竟然被微软的实体框架忽略了?!所以我很可能正在做一些相当愚蠢的事情。

最后,问题...

我认为主要问题是关于我的“数据库设计”。由于我是 EF 的新手并且边走边学,因此我可能有好几次都走错了方向(我的设计有问题吗?)。由于 EF 专家很好地代表了 SO,我非常渴望了解我可以使用哪些替代方案来实现相同的目标(多租户、共享用户、可在 azure 中部署)。我是否应该使用一个DbContext并且仍然能够部署具有共享的多租户 Web 应用程序?Users数据库的多租户 Web 应用程序?

我真的很感谢你的帮助!


学到的东西:


  • PS:我意识到这是一个很长的问题。随意编辑问题并删除不相关的部分以提高可读性。
  • PPS:如果需要,我可以分享更多代码

非常感谢你。我很乐意为您的所有努力点赞!

4

1 回答 1

1

我不太明白你为什么需要跨数据库关系。假设您的应用程序可以与用户数据库和租户数据库这两个数据库进行通信,它可以轻松地使用第一个数据库进行身份验证,然后按照“按名称”约定在租户数据库中查找相关用户。

例如,如果您使用用户数据库对用户 JOHN 进行身份验证,则您在租户数据库中搜索用户 JOHN。

这将更容易实现并且仍然符合您的要求,用户与他们的密码和用户记录的“影子副本”一起存储在用户数据库中,但没有密码存储在租户数据库中,并且这两者之间没有物理关系。

于 2013-03-02T23:33:58.400 回答