如何使用 EF Core 跨租户数据库处理共享查找表?

How to handle shared lookup tables across tenant databases using EF Core?

我们正在开发多租户应用程序。设计是这样的,每个租户都有自己的数据库(在同一台服务器上),每个数据库都有相同的模式。

系统有特定的查找 table 定义在所有系统中将保持不变的值。例如,州、县、性别等。设计说明这些将在 "Control" 数据库中。 "Control" 数据库由我们的组织管理——因此租户可以从查找 table 中读取数据,但不能将数据写入 table。

这里的想法是我们要避免在每个数据库中重复这些查找 table 和数据。如果我们必须更改一个值或添加一个新值,我们可以在一个 table 中完成,而不是必须在每个租户数据库中更新它。

问题在于,对于 EF Core,我们有两个 DbContext——一个与租户的数据相关联,一个与控制数据库相关联。似乎没有办法定义跨数据库关系。

例子

//Table exists in each Tenant Database
public class Client{
    public int Id {get; set;}
    public string Firstname {get; set;}
    public string Lastname {get; set;}

    //Table of Counties defined in "Control" database
    public int CountyOfResidenceId { get; set;}
    public County CountyOfResidence {get; set;}

}

我能想到的处理此设计的唯一方法是必须(在我的 API 控制器中)验证来自客户端的 ID(通过查找控制数据库)并手动填充 CountyOfResidence(以及所有其他 "lookup" 属性)对于从数据库中读取的每个客户端。

那些创建多租户应用程序(其中每个租户都需要拥有自己的数据库)的人通常如何处理这种情况?

在使用 DB-per-Tenant 时,我利用复制来控制跨租户数据库的查找表。尝试将 "common" 表集中在一个单独的数据库中的问题是您失去了有效执行 FK 关系的能力。使用 SQL 服务器,您可以使用跨数据库的检查约束来代替 FK,但这会产生性能成本,IMO 值得将这些成本相对较低每个租户数据库中的表。鉴于这些应该是真正通用的表,因此不应期望它们会非常频繁地更改(如果有的话)。单向复制非常简单,设置起来非常简单,甚至可以作为一项可安排的作业手动管理。

我构建多租户应用程序的方式是主 DBContext/DB 仅处理身份验证、版本控制、维护跟踪,并在身份验证后移交租户的数据库连接字符串。