EF:关于跨数据库关系的数据库设计问题

时间:2013-03-02 21:03:07

标签: c# entity-framework database-design ef-code-first

摘要

我目前正在构建一个(非常直接的?)多租户网络应用程序原型,用户(存储在数据库 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

中不存在交叉数据库关系

所以我开始谷歌搜索,发现这个功能根本不受支持。这让我想到,我是否应该将EF用于这样的应用程序?我应该转向NHibernate吗?

但我也无法想象微租户的实体框架会忽略多租户应用的巨大市场?所以我很可能正在做一些相当愚蠢的事情。

最后,问题......

我认为主要问题是我的'数据库设计'。由于我是EF的新手并且在我学习的过程中学习,我可能会在几次错误的转弯(我的设计被破坏了吗?)。由于SO很好地代表了EF专家,我非常渴望了解我可以使用哪些替代方案来实现相同的目标(多租户,共享用户,可以在azure中部署)。我应该使用一个DbContext还是能够部署具有共享Users数据库的多租户Web应用程序吗?

我真的很感谢你的帮助!


学到的东西:


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

提前非常感谢你。我很乐意为你所有的努力给予奖励!

1 个答案:

答案 0 :(得分:1)

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

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

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