abpframework / abp

Open-source web application framework for ASP.NET Core! Offers an opinionated architecture to build enterprise software solutions with best practices on top of the .NET. Provides the fundamental infrastructure, cross-cutting-concern implementations, startup templates, application modules, UI themes, tooling and documentation.
https://abp.io
GNU Lesser General Public License v3.0
12.91k stars 3.44k forks source link

Automatic Database Migration on Startup sample #17946

Open lgadola opened 1 year ago

lgadola commented 1 year ago

Is there an existing issue for this?

Is your feature request related to a problem? Please describe the problem.

In Release notes of 7.4 there is a brief description on how to perform automatic database migrations on startup. I did not manage to accomplish this.

Describe the solution you'd like

Please provide a sample project with automatic database migration enabled at startup of the web application.

Additional context

No response

maliming commented 1 year ago

Do you mean EfCoreRuntimeDatabaseMigratorBase class?

lgadola commented 1 year ago

yes, the description is: Create a class that derives from EfCoreRuntimeDatabaseMigratorBase class, override and implement its SeedAsync method. And lastly, execute the CheckAndApplyDatabaseMigrationsAsync method of your class in the OnPostApplicationInitializationAsync method of your module class. Create a class that derives from DatabaseMigrationEventHandlerBase class, override and implement its SeedAsync method. Then, whenever a new tenant is created or a tenant's connection string is changed then the SeedAsync method will be executed.

maliming commented 1 year ago

I think the description is very clear, you can just follow it.

lgadola commented 1 year ago

I tried, but getting None of the constructors found on type 'MediSpens.EntityFrameworkCore.MediSpensEfCoreRuntimeDatabaseMigrator' can be invoked with the available services and parameters: Cannot resolve parameter 'System.String databaseName' of constructor 'Void .ctor(System.String, Volo.Abp.Uow.IUnitOfWorkManager, System.IServiceProvider, Volo.Abp.MultiTenancy.ICurrentTenant, Volo.Abp.DistributedLocking.IAbpDistributedLock, Volo.Abp.EventBus.Distributed.IDistributedEventBus, Microsoft.Extensions.Logging.ILoggerFactory)'.

My AbpModule: public override async Task OnPostApplicationInitializationAsync(ApplicationInitializationContext context) { var myService = context.ServiceProvider.GetService<MediSpensEfCoreRuntimeDatabaseMigrator>(); await myService.CheckAndApplyDatabaseMigrationsAsync(); }

My database migrator:

`using Microsoft.Extensions.Logging; using System; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; using Volo.Abp.DistributedLocking; using Volo.Abp.EntityFrameworkCore.Migrations; using Volo.Abp.EventBus.Distributed; using Volo.Abp.MultiTenancy; using Volo.Abp.Uow;

namespace MediSpens.EntityFrameworkCore { [Dependency(ReplaceServices = true)] public class MediSpensEfCoreRuntimeDatabaseMigrator : EfCoreRuntimeDatabaseMigratorBase { public MediSpensEfCoreRuntimeDatabaseMigrator(string databaseName, IUnitOfWorkManager unitOfWorkManager, IServiceProvider serviceProvider, ICurrentTenant currentTenant, IAbpDistributedLock abpDistributedLock, IDistributedEventBus distributedEventBus, ILoggerFactory loggerFactory) : base(databaseName, unitOfWorkManager, serviceProvider, currentTenant, abpDistributedLock, distributedEventBus, loggerFactory) { } public override Task CheckAndApplyDatabaseMigrationsAsync() { return base.CheckAndApplyDatabaseMigrationsAsync(); } protected override Task SeedAsync() { return base.SeedAsync(); } } } `

maliming commented 1 year ago

hi

You can try removing the databaseName from the `TestEfCoreRuntimeDatabaseMigrator's ctor, then passing a fixed string to the base class ctor.