问题
I just need confirmation I'm on the right track with this aspect I'm trying to implement.
Step 1: for each tenant create a new context eg
public class TenantOneContext : AbpZeroDbContext<Tenant, Role, User, TenantOneContext{
public DbSet<MyModel1> MyModel1S { get; set; }
public DbSet<MyModel1> MyModel2S { get; set; }
Step 2: I assume using a naming convention, that each context that exists, there is an associated [contextname]Configurer eg
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);
}
Step 3: create new [contextname]Factory for each tenant-context eg
public class TenantOneContextFactory : IDesignTimeDbContextFactory<TenantOneContext>
In the module that inherits AbpModule
- add some code to do custom connection string resolving eg
public class MyAppEntityFrameworkModule : AbpModule {
//new code to resolve conn strings / tennant
Configuration.ReplaceService<IConnectionStringResolver, DbPerTenantConnectionStringResolver>(DependencyLifeStyle.Transient);
I think that is it - but looking for confirmation...:-)
回答1:
You probably don't need a different DbContext
for each tenant, just a different connection.
if so, is there a naming convention for mapping the conn strings ? or where does the mapping take place?
The connection string is stored in Tenant entity:
public const int MaxConnectionStringLength = 1024;
[StringLength(MaxConnectionStringLength)]
public virtual string ConnectionString { get; set; }
The mapping takes places in 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;
来源:https://stackoverflow.com/questions/47349344/database-per-tenant-a-step-by-step-example-to-confirm-my-thinking