我只需要确认我正在努力实现这一方面的正确轨道。
第1步:为每个租户创建一个新的上下文,例如
public class TenantOneContext : AbpZeroDbContext<Tenant, Role, User, TenantOneContext{
public DbSet<MyModel1> MyModel1S { get; set; }
public DbSet<MyModel1> MyModel2S { get; set; }
第2步: 我假设使用命名约定,存在的每个上下文,都有一个关联的[contextname]配置器,例如
public static class TenantOneContextConfigurer
{
public static void Configure(DbContextOptionsBuilder<TenantOneContext> builder, string connectionString)
{
builder.UseSqlServer(connectionString);
}
public static void Configure(DbContextOptionsBuilder<TenantOneContext> builder, DbConnection connection)
{
builder.UseSqlServer(connection);
}
第3步:为每个租户上下文创建新的[contextname]工厂,例如
public class TenantOneContextFactory : IDesignTimeDbContextFactory<TenantOneContext>
在继承AbpModule
的模块中 - 添加一些代码来执行自定义连接字符串解析,例如
public class MyAppEntityFrameworkModule : AbpModule {
//new code to resolve conn strings / tennant
Configuration.ReplaceService<IConnectionStringResolver, DbPerTenantConnectionStringResolver>(DependencyLifeStyle.Transient);
我认为就是这样 - 但寻找确认......: - )
答案 0 :(得分:3)
对于每个租户,您可能不需要不同的DbContext
,只需要不同的连接。
如果是这样,是否有映射conn字符串的命名约定?或者映射在哪里发生?
连接字符串存储在Tenant实体:
中public const int MaxConnectionStringLength = 1024;
[StringLength(MaxConnectionStringLength)]
public virtual string ConnectionString { get; set; }
映射发生在DbPerTenantConnectionStringResolver:
if (args.TenantId == null)
{
// Requested for host
return base.GetNameOrConnectionString(args);
}
var tenantCacheItem = _tenantCache.Get(args.TenantId.Value);
if (tenantCacheItem.ConnectionString.IsNullOrEmpty())
{
// Tenant has no dedicated database
return base.GetNameOrConnectionString(args);
}
return tenantCacheItem.ConnectionString;