using System.Data.Entity; using System.Data.Entity.Migrations; using System.Transactions; using Abp.Dependency; using Abp.Domain.Uow; using Abp.MultiTenancy; using IwbZero.Data; using IwbZero.MultiTenancy; namespace IwbZero.EntityFramework { public abstract class IwbZeroDbMigrator : IIwbDbMigrator, ITransientDependency where TDbContext : DbContext where TConfiguration : DbMigrationsConfiguration, IMultiTenantSeed, new() { private readonly IUnitOfWorkManager _unitOfWorkManager; private readonly IDbPerTenantConnectionStringResolver _connectionStringResolver; private readonly IIocResolver _iocResolver; protected IwbZeroDbMigrator( IUnitOfWorkManager unitOfWorkManager, IDbPerTenantConnectionStringResolver connectionStringResolver, IIocResolver iocResolver) { _unitOfWorkManager = unitOfWorkManager; _connectionStringResolver = connectionStringResolver; _iocResolver = iocResolver; } public virtual void CreateOrMigrateForHost() { CreateOrMigrate(null); } public virtual void CreateOrMigrateForTenant(TenantBase tenant) { if (string.IsNullOrEmpty(tenant.ConnectionString)) { return; } CreateOrMigrate(tenant); } protected virtual void CreateOrMigrate(TenantBase tenant) { var args = new DbPerTenantConnectionStringResolveArgs( tenant == null ? null : tenant.Id as int?, tenant == null ? MultiTenancySides.Host : 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 = _iocResolver.ResolveAsDisposable(new { nameOrConnectionString })) { var dbInitializer = new MigrateDatabaseToLatestVersion( true, new TConfiguration { Tenant = tenant }); dbInitializer.InitializeDatabase(dbContext.Object); _unitOfWorkManager.Current.SaveChanges(); uow.Complete(); } } } } }