#nullable enable using System.Transactions; using Abp.Dependency; using Abp.Domain.Uow; using Abp.EntityFrameworkCore; using Abp.Extensions; using Microsoft.EntityFrameworkCore; using VberZero.BaseSystem.MultiTenancy; using VberZero.Data; using VberZero.MultiTenancy; namespace VberZero.EntityFramework; public abstract class VzDbMigrator : IVzDbMigrator, ITransientDependency where TDbContext : DbContext { private readonly IUnitOfWorkManager _unitOfWorkManager; private readonly IDbPerTenantConnectionStringResolver _connectionStringResolver; private readonly IDbContextResolver _dbContextResolver; protected VzDbMigrator( IUnitOfWorkManager unitOfWorkManager, IDbPerTenantConnectionStringResolver connectionStringResolver, IDbContextResolver dbContextResolver) { _unitOfWorkManager = unitOfWorkManager; _connectionStringResolver = connectionStringResolver; _dbContextResolver = dbContextResolver; } public virtual void CreateOrMigrateForHost() { CreateOrMigrateForHost(null); } public virtual void CreateOrMigrateForHost(Action? seedAction) { CreateOrMigrate(null, seedAction); } public virtual void CreateOrMigrateForTenant(Tenant tenant) { CreateOrMigrateForTenant(tenant, null); } public virtual void CreateOrMigrateForTenant(Tenant? tenant, Action? seedAction) { if (tenant != null && tenant.ConnectionString.IsNullOrEmpty()) { return; } CreateOrMigrate(tenant, seedAction); } protected virtual void CreateOrMigrate(Tenant? tenant, Action? seedAction) { var args = new DbPerTenantConnectionStringResolveArgs( tenant?.Id, tenant == null ? Abp.MultiTenancy.MultiTenancySides.Host : Abp.MultiTenancy.MultiTenancySides.Tenant ) { ["DbContextType"] = typeof(TDbContext), ["DbContextConcreteType"] = typeof(TDbContext) }; var nameOrConnectionString = ConnectionStringHelper.GetConnectionString( _connectionStringResolver.GetNameOrConnectionString(args) ); using var uow = _unitOfWorkManager.Begin(TransactionScopeOption.Suppress); using var dbContext = _dbContextResolver.Resolve(nameOrConnectionString, null); dbContext.Database.Migrate(); seedAction?.Invoke(dbContext); _unitOfWorkManager.Current.SaveChanges(); uow.Complete(); } }