entityframework 核心多租户的最佳方法
Best approach for entityframework core multi tenancy
我们基于 ASP.NET Core 和 EFCore 开发了更大的 SaaS 应用程序。我们用数据库来区分租户,也就是说我们每个租户一个数据库。
通过自定义中间件根据客户端的任何传入请求迁移数据库。这是必需的,因为在租户在我们的 SSO 服务器上注册后,应用程序应该立即可用。
所以管道看起来像这样:
- 身份验证中间件(ASP.NET 核心标准)
- UserResolverMiddleware(从 JWT 令牌中提取 TenantID 并将其添加到 HttpContext.Items)
- TenantDatabaseInitializerMiddleware(通过传递ConnectionString中的tenantid构造一个TenantDbContext对象并开始迁移)
不幸的是,这有一些缺点,我后来认识到:
- TenantDatabaseInitializer 有时会使用不同租户的 TenantDbContext。因此没有迁移数据库,整个请求失败。
- 如果同一个租户有很多传入请求,迁移往往会重叠并失败。 (中间件正在捕获抛出的 InvalidOperationExceptions,但这似乎不是一个好的解决方案)。
- 它创建了很多数据库。
- 请求可能需要很长时间才能完成(检查迁移)。
长篇介绍,简短问题:谁能判断这个迁移工作流程是否是一个好的做法?如果没有:您是否知道我如何实现多租户?
我了解了 EFCore 2.0 中的全局查询过滤器,但我不确定这种方法在数据隔离方面的安全性。
谢谢!
我认为为每个租户创建一个数据库是不切实际的。如果你有2000个租户,那么你就得维护2000个数据库实例!
我建议为所有应用程序和租户使用 1 个数据库。并在大多数表中添加 TenantId
,以便您可以找出该特定记录属于哪个租户。
我们基于 ASP.NET Core 和 EFCore 开发了更大的 SaaS 应用程序。我们用数据库来区分租户,也就是说我们每个租户一个数据库。
通过自定义中间件根据客户端的任何传入请求迁移数据库。这是必需的,因为在租户在我们的 SSO 服务器上注册后,应用程序应该立即可用。
所以管道看起来像这样:
- 身份验证中间件(ASP.NET 核心标准)
- UserResolverMiddleware(从 JWT 令牌中提取 TenantID 并将其添加到 HttpContext.Items)
- TenantDatabaseInitializerMiddleware(通过传递ConnectionString中的tenantid构造一个TenantDbContext对象并开始迁移)
不幸的是,这有一些缺点,我后来认识到:
- TenantDatabaseInitializer 有时会使用不同租户的 TenantDbContext。因此没有迁移数据库,整个请求失败。
- 如果同一个租户有很多传入请求,迁移往往会重叠并失败。 (中间件正在捕获抛出的 InvalidOperationExceptions,但这似乎不是一个好的解决方案)。
- 它创建了很多数据库。
- 请求可能需要很长时间才能完成(检查迁移)。
长篇介绍,简短问题:谁能判断这个迁移工作流程是否是一个好的做法?如果没有:您是否知道我如何实现多租户?
我了解了 EFCore 2.0 中的全局查询过滤器,但我不确定这种方法在数据隔离方面的安全性。
谢谢!
我认为为每个租户创建一个数据库是不切实际的。如果你有2000个租户,那么你就得维护2000个数据库实例!
我建议为所有应用程序和租户使用 1 个数据库。并在大多数表中添加 TenantId
,以便您可以找出该特定记录属于哪个租户。