Closed stuyun closed 5 years ago
Hi @stuyun . Can you elaborate a little more on the question? Are you moving away from Abp? I don't use Abp myself and this library stays pretty close to standard ASP.NET Core and EF Core conventions.
Using Finbuckle.MultiTenant with existing database should be as simple as using EF Core with an existing database except that you alter the created context to inherit from MultiTenantDbContext
rather than DbContext
. You would then create a new migration and apply it so that the TenantID
column is created in the database (if it doesn't already exist).
I know microsoft migration info but Feature update too many tenants too many databases can not batch migration problem abp There is a batch migration feature
https://aspnetboilerplate.com/Templates abp create demo
public class MultiTenantMigrateExecuter : ITransientDependency
{
private readonly Log _log;
private readonly AbpZeroDbMigrator _migrator;
private readonly IRepository
public MultiTenantMigrateExecuter(
AbpZeroDbMigrator migrator,
IRepository<Tenant> tenantRepository,
Log log,
IDbPerTenantConnectionStringResolver connectionStringResolver)
{
_log = log;
_migrator = migrator;
_tenantRepository = tenantRepository;
_connectionStringResolver = connectionStringResolver;
}
public bool Run(bool skipConnVerification)
{
var hostConnStr = CensorConnectionString(_connectionStringResolver.GetNameOrConnectionString(new ConnectionStringResolveArgs(MultiTenancySides.Host)));
if (hostConnStr.IsNullOrWhiteSpace())
{
_log.Write("Configuration file should contain a connection string named 'Default'");
return false;
}
_log.Write("Host database: " + ConnectionStringHelper.GetConnectionString(hostConnStr));
if (!skipConnVerification)
{
_log.Write("Continue to migration for this host database and all tenants..? (Y/N): ");
var command = Console.ReadLine();
if (!command.IsIn("Y", "y"))
{
_log.Write("Migration canceled.");
return false;
}
}
_log.Write("HOST database migration started...");
try
{
_migrator.CreateOrMigrateForHost(SeedHelper.SeedHostDb);
}
catch (Exception ex)
{
_log.Write("An error occured during migration of host database:");
_log.Write(ex.ToString());
_log.Write("Canceled migrations.");
return false;
}
_log.Write("HOST database migration completed.");
_log.Write("--------------------------------------------------------");
var migratedDatabases = new HashSet<string>();
var tenants = _tenantRepository.GetAllList(t => t.ConnectionString != null && t.ConnectionString != "");
for (var i = 0; i < tenants.Count; i++)
{
var tenant = tenants[i];
_log.Write(string.Format("Tenant database migration started... ({0} / {1})", (i + 1), tenants.Count));
_log.Write("Name : " + tenant.Name);
_log.Write("TenancyName : " + tenant.TenancyName);
_log.Write("Tenant Id : " + tenant.Id);
_log.Write("Connection string : " + SimpleStringCipher.Instance.Decrypt(tenant.ConnectionString));
if (!migratedDatabases.Contains(tenant.ConnectionString))
{
try
{
_migrator.CreateOrMigrateForTenant(tenant);
}
catch (Exception ex)
{
_log.Write("An error occured during migration of tenant database:");
_log.Write(ex.ToString());
_log.Write("Skipped this tenant and will continue for others...");
}
migratedDatabases.Add(tenant.ConnectionString);
}
else
{
_log.Write("This database has already migrated before (you have more than one tenant in same database). Skipping it....");
}
_log.Write(string.Format("Tenant database migration completed. ({0} / {1})", (i + 1), tenants.Count));
_log.Write("--------------------------------------------------------");
}
_log.Write("All databases have been migrated.");
return true;
}
private static string CensorConnectionString(string connectionString)
{
var builder = new DbConnectionStringBuilder { ConnectionString = connectionString };
var keysToMask = new[] { "password", "pwd", "user id", "uid" };
foreach (var key in keysToMask)
{
if (builder.ContainsKey(key))
{
builder[key] = "*****";
}
}
return builder.ToString();
}
}
}
var tenants = _tenantRepository.GetAllList(t => t.ConnectionString != null && t.ConnectionString != ""); for (var i = 0; i < tenants.Count; i++) { var tenant = tenants[i]; _log.Write(string.Format("Tenant database migration started... ({0} / {1})", (i + 1), tenants.Count)); _log.Write("Name : " + tenant.Name); _log.Write("TenancyName : " + tenant.TenancyName); _log.Write("Tenant Id : " + tenant.Id); _log.Write("Connection string : " + SimpleStringCipher.Instance.Decrypt(tenant.ConnectionString));
if (!migratedDatabases.Contains(tenant.ConnectionString))
{
try
{
_migrator.CreateOrMigrateForTenant(tenant);
}
catch (Exception ex)
{
_log.Write("An error occured during migration of tenant database:");
_log.Write(ex.ToString());
_log.Write("Skipped this tenant and will continue for others...");
}
migratedDatabases.Add(tenant.ConnectionString);
}
else
{
_log.Write("This database has already migrated before (you have more than one tenant in same database). Skipping it....");
}
_log.Write(string.Format("Tenant database migration completed. ({0} / {1})", (i + 1), tenants.Count));
_log.Write("--------------------------------------------------------");
}
_log.Write("All databases have been migrated.");
return true;
It supports simultaneous migration of databases for all tenants
@stuyun I apologize for not responding sooner. Unfortunately I don't have a good answer. Finbuckle.MultiTenant doesn't have batch migration functionality as it is more on the library side of things than a full framework like abp. Were you able to make any progress?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
efcore How do you migrate independent databases if you have many libraries Abp database migration is recommended https://github.com/aspnetboilerplate/aspnetboilerplate