Add new table in existing plugin without uninstalling

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
4 years ago
Hi,
   I want to add a new table to my existing plugin(which already has a few tables). I don't want to uninstall & re-install the plugin for this. Please let me know how this can be achieved. The plugin is built on nopCommerce version 3.90.

In my object context, I am calling this method for table creation.

 
public string CreateDatabaseScript()
        {
            return ((IObjectContextAdapter)this).ObjectContext.CreateDatabaseScript();
        }

        public void Install()
        {
            //create the table
            var dbScript = CreateDatabaseScript();
            Database.ExecuteSqlCommand(dbScript);
            SaveChanges();
        }


Thanks in advance.
4 years ago
Hi,

You can write a SQL script to create the new table and execute it against the database.

Regards,
Stoyan
4 years ago
Maybe you can use EF migration to create a new table, use ef migration can update table fields and add new table, hope you can try.
4 years ago
I recommend to use FluentMigrator to do migration work since setting up EF migration with the plugin architecture is pretty complex and difficult to get the most of it. There are not a lot of documentation on how to setup it correctly with Nop but I can show what I got so far on my project.

First, you can add the Nuget package inside your plugin. Then, within your PluginStartup that inherits from INopStartup, configure the migrator like this:


public void ConfigureServices(IServiceCollection services, IConfiguration configuration)
{
    var dataSettings = DataSettingsManager.LoadSettings();
    services.AddFluentMigratorCore().ConfigureRunner(builder =>
    {
        builder.AddSqlServer()
           .WithGlobalConnectionString(dataSettings.DataConnectionString)
           .WithVersionTable(new PluginMigrationVersionTable())
           .ScanIn(typeof(CreatePluginSchemas).Assembly)
           .For.Migrations();
    }).AddLogging(lb => lb.AddEventSourceLogger());
}


In that code above, I loaded the db setting for the connection string then pass it through the configure so it can be use at runtime. PluginMigrationVersionTable is the custom version table so you can follow FluentMigrator doc on how to get it work, otherwise, just not using that. CreatePluginSchemas is my first migration class that create all the db tables instead of using the default CreateDatabaseScript().

Next, I want the migration to be run at runtime when the plugin is loading, so I have it configured like this:

public void Configure(IApplicationBuilder application)
{
    var dataSettings = DataSettingsManager.LoadSettings();
    if (!dataSettings?.IsValid ?? true)
        return;
    
    ApplyMigration(application);
}

private void ApplyMigration(IApplicationBuilder application)
{
     try
     {
         using (var serviceScope =
           application.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
         {
             var runner = serviceScope.ServiceProvider.GetRequiredService<IMigrationRunner>();
             try
             {
                 runner.MigrateUp();
             }
             catch (Exception)
             {
                 // ignored
             }
          }
      }
      catch (Exception)
      {
           // ignored
      }
}


Finally, in your ObjectContext class, instead of using ExecuteSqlScript(GenerateCreateScript()) in the Install method, just use SaveChanges() and nothing else.

Afterward, you can add any migration class based on FluentMigrator as much as you need and all of them will be executed during the plugin loading process.

Note: This is based on the lastest Nop that has been converted to .Net Core. You can applied the same approach to .Net Framework version, but I would imagine it could take a little more setup.
4 years ago
Thank you all for your solutions.
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.