多租户 EF Core 实现多租户

软件即服务和多租户
SaaS(软件和服务)与其他应用程序不同的主要特点是,它使客户能够在使用应用程序时根据使用量付费。他们不需要为软件购买许可证,也不需要安装、托管和管理软件。该领域的所有操作都由提供SaaS软件的组织负责。
多租户是实现SaaS的关键因素。它可以使多个企业或组织的用户共享同一个系统或程序组件,而不破坏这些组织的数据安全性,保证组织间的数据隔离。
多租户数据隔离方案
单数据库 如果软件系统仅部署一个实例,并且所有租户的数据都是存放在一个数据库里面的,那么可以通过一个 TenantId (租户 Id) 来进行数据隔离。那么当我们执行 SELECT 操作的时候就会附加上当前登录用户租户 Id 作为过滤条件,那么查出来的数据也仅仅是当前租户的数据,而不会查询到其他租户的数据。 这是共享程度最高、隔离级别最低的模式。需要在设计开发时加大对安全的开发量。多数据库 为每一个租户提供一个单独的数据库,在用户登录的时候根据用户对应的租户 ID,从一个数据库连接映射表获取到当前租户对应的数据库连接字符串,并且在查询数据与写入数据的时候,不同租户操作的数据库是不一样的。 这种方案的用户数据隔离级别最高,安全性最好,但维护和购置成本较高.两者之间还有一个方案:共享数据库和独立Schema,但是实际应用应该很少。
使用英孚核心简单实现多租户
获取租户标识有两种方法:
根据登录用户获取. 作为登录用户的附加信息, 比如把租户 Id 放到Json Web Token里面或者根据用户 Id 去数据库里取对应的租户 Id.根据企业或组织用户的Host获取. 部署的时候会给每个企业或组织分配一个单独的Host, 并在数据库里维护着一个租户 Id 和 Host 的映射表. 查询的时候根据 Host 去取对应的租户 Id.在编译框架时,我们最好把租户Id的处理(查询时过滤,保存时赋值)放在数据访问的最底层,并自动实现,这样业务逻辑开发人员就可以尽量少关注租户Id,而像普通应用一样开发多租户应用。
EF Core在2.0版引入了“模型级查询过滤器”的新功能,可以帮助开发者实现软删除和多租户。
单一数据库实现
下面使用英孚核心来简单实现单数据库和多租户的演示。主机用于获取租户标识。
创建 Tenant 实体类和 TenantsContext, 用于存储租户 Id 和 Host 的映射, 并根据 Host 从数据库里获取 Id.

多租户 EF Core 实现多租户


文章图片

多租户 EF Core 实现多租户


文章图片

创建租户提供者,用于从HttpContext中识别主机,并访问租户文本以获取租户标识。

多租户 EF Core 实现多租户


文章图片

创建博客实体类和博客上下文有几个注意事项
BaseEntity 类里面包含 TenantId, 所以需要共享数据的表都要继承自这个基类.BloggingContext 的构造函数里面加入参数 ITenantProvider tenantProvider, 用于获取租户 Id.在 OnModelCreating 方法里面对所有继承于 BaseEntity 的实体类配置全局过滤 builder.Entity<T>().HasQueryFilter(e => e.TenantId == _tenantId).重载 SaveChangesAsync 等方法, 保存数据的时候自动赋值 TenantId.

多租户 EF Core 实现多租户


文章图片

多租户 EF Core 实现多租户

推荐阅读