Open Closed

How to migrate dataset for Plug-In #7800


User avatar
0
niall created
  • ABP Framework version: v8.2.2
  • UI Type: MVC
  • Database System: EF Core (SQL Server, Oracle, MySQL, PostgreSQL, etc..)
  • Tiered (for MVC) or Auth Server Separated (for Angular): yes
  • Exception message and full stack trace:
  • Steps to reproduce the issue:

I created a plugin with follow command:

abo new My.Plugin -t module

when i run AuthServer or Web.Unified,throw a exception, tip need create dataset. So i need run 'Update-Database' to create it.

My question is how to auto create database when plugin is run?

I found some document at https://abp.io/docs/latest/framework/architecture/modularity/plugin-modules, like this:

The Plugin may check if the database tables does exists and create the tables on the application startup or migrate them if the plug-in has been updated and requires some schema changes. You can use EF Core's migration API to do that.

But how to implement it,Is there a example?

Thanks~


4 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    You can get the dbcontext migrate and seed the data in OnPreApplicationInitializationAsync method of your module.

    public async override Task OnPreApplicationInitializationAsync(ApplicationInitializationContext context)
    {
        using var uow = context.ServiceProvider.GetRequiredService<IUnitOfWorkManager>().Begin();
        {
            var dbContext = await context.ServiceProvider.GetRequiredService<IDbContextProvider<ServerDbContext>>().GetDbContextAsync();
            if ((await dbContext.Database.GetPendingMigrationsAsync()).Any())
            {
                await dbContext.Database.MigrateAsync();
            }
    
            await uow.CompleteAsync();
        }
    
        await context.ServiceProvider
            .GetRequiredService<IDataSeeder>()
            .SeedAsync();
    }
    
  • User Avatar
    0
    niall created

    I added your codes, got a exception:

    [11:23:24 FTL] Host terminated unexpectedly!
    Volo.Abp.AbpInitializationException: An error occurred during the initialize Volo.Abp.Modularity.OnPreApplicationInitializationModuleLifecycleContributor phase of the module XTC.License.LicenseAuthServerModule, XTC.License.AuthServer, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null: An exception was thrown while activating XTC.License.EntityFrameworkCore.AuthServerDbContext.. See the inner exception for details.
     ---> Autofac.Core.DependencyResolutionException: An exception was thrown while activating XTC.License.EntityFrameworkCore.AuthServerDbContext.
     ---> Autofac.Core.DependencyResolutionException: None of the constructors found on type 'XTC.License.EntityFrameworkCore.AuthServerDbContext' can be invoked with the available services and parameters:
    Cannot resolve parameter 'Microsoft.EntityFrameworkCore.DbContextOptions`1[XTC.License.EntityFrameworkCore.AuthServerDbContext] options' of constructor 'Void .ctor(Microsoft.EntityFrameworkCore.DbContextOptions`1[XTC.License.EntityFrameworkCore.AuthServerDbContext])'.
    
    See https://autofac.rtfd.io/help/no-constructors-bindable for more info.
       at Autofac.Core.Activators.Reflection.ReflectionActivator.<>c__DisplayClass14_0.<UseSingleConstructorActivation>b__0(ResolveRequestContext context, Action`1 next)
       at Autofac.Core.Resolving.Middleware.DelegateMiddleware.Execute(ResolveRequestContext context, Action`1 next)
       at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext context)
       at Autofac.Core.Resolving.Middleware.DisposalTrackingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
       at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.&lt;&gt;c__DisplayClass14_0.&lt;BuildPipeline&gt;b__1(ResolveRequestContext context)
       at Autofac.Builder.RegistrationBuilder`3.<>c__DisplayClass41_0.<PropertiesAutowired>b__0(ResolveRequestContext context, Action`1 next)
    

    So i modify the code to var dbContext = factory.CreateDbContext(null);, like this:

        public async override Task OnPreApplicationInitializationAsync(ApplicationInitializationContext context)
        {
            using var uow = context.ServiceProvider.GetRequiredService&lt;IUnitOfWorkManager&gt;().Begin();
            {
                var factory = new AuthServerDbContextFactory();
                var dbContext = factory.CreateDbContext(null);
                //var dbContext = await context.ServiceProvider.GetRequiredService&lt;IDbContextProvider&lt;AuthServerDbContext&gt;>().GetDbContextAsync();
                if ((await dbContext.Database.GetPendingMigrationsAsync()).Any())
                {
                    await dbContext.Database.MigrateAsync();
                }
    
                await uow.CompleteAsync();
            }
        }
    

    now everything is ok, is my modify right?

  • User Avatar
    0
    niall created

    I resolved it, Thanks!

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Great!

Made with ❤️ on ABP v9.0.0-preview Updated on September 19, 2024, 10:13