我正在迁移一个单租户、单数据库 ASP.NET Core Web API 项目,该项目使用 Azure AD 和 DistributedSqlServerCache 来支持多租户、多数据库方法。
我们的应用程序将支持多个租户的 Azure AD 登录,每个租户都有自己的数据库以实现更好的隔离。
这对于 Entity Framework Core 有很好的记录,还有 代码示例,但是没有任何关于为令牌缓存采用多租户、多数据库方法的明确信息。官方多租户 Azure AD 文档确实提到了令牌缓存,但没有讨论多数据库方法。
问题
services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = connectionString;
options.TableName = "DistributedCache";
options.SchemaName = "cache";
});
此代码将执行一次,因此我无法将连接字符串更改为正在执行当前请求的用户的租户。有谁知道根据当前请求/当前用户将应用程序指向不同缓存的方法?例如,只要我能够访问当前的
IServiceProvider
,我就可以获取当前的
HttpContext
并找到租户并以此为基础建立我的连接字符串。
例如:
var catalogContext = services.BuildServiceProvider().GetService<CatalogContext>();
var tenants = catalogContext.Tenants.ToList();
foreach (var tenant in tenants)
{
var connectionString = configuration.GetConnectionString(tenant.ConnectionStringName);
services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = connectionString;
options.SchemaName = "dbo";
options.TableName = "Cache";
});
}
然后像平常一样在 DbContext.OnConfiguring 中选择数据库。 (如何设置上下文取决于您)
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
var tenantData = _catalogContext.Tenants.FirstOrDefault(t => t.TenantId == _contextTenantId) ??
new Tenant { ConnectionStringName = "DefaultDatabaseConnectionString" };
var connectionString = _configuration.GetConnectionString(tenantData.ConnectionStringName);
optionsBuilder
.UseSqlServer(connectionString,
optionAction =>
{
optionAction.MigrationsHistoryTable(DatabaseConstants.MigrationsHistoryTableName,
"DatabaseSchemaName")
.CommandTimeout(120)
.MaxBatchSize(250);
});
}
}