Having developed a couple of plugins for nopCommerce, we’ve always found default nopCommerce plugin documentation missing out on one very important feature. That is Entity Framework Migrations support.

While the method written in the documentation works well if future releases of your plugin won’t be modifying the database much and you’d be providing upgrade scripts for the same, providing upgrade scripts either is just not good enough for a non-geek store owner. For would he focus on running his own business or running your upgrade scripts?

Why not use Entity Framework Migrations(EFMigrations), aren’t they cool?

Exactly. While working on mobSocial, we thought that we’d include EFMigrations, so store owner won’t have to rely on upgrade scripts for upgrading to latest versions. After all which applications would get frequent database upgrades than a social network? However the issue with EFMigrations was that store owners would require VisualStudio to upgrade their database to latest migrations to run commands (an even worse thing than running the upgrade scripts IMHO). Why not automate that thing, we thought. Let the store owner replace existing plugin and restart their nopCommerce installation and bam…database should upgrade to latest versions. Sounds interesting? Let’s dive in to achieve that.

For this tutorial, we’ll create a simple nopCommerce plugin in which we’ll create a single entity. But the process is same for any plugin with any number of tables (link to plugin source provided at the end).

Step 1: Setup a nopCommerce plugin project (or use your existing project of course)

This should be fairly straightforward if you have worked with nopCommerce for quite a while. In case you are a beginner, I’d recommend you to read this nopCommerce tutorial and then this, which will give you a fair knowledge about creating a nopCommerce plugin.

2016-05-01_163619

For the sake of brevity, we’d be creating only the files necessary to demonstrate the concept. We, therefore, stick to the following project structure.

2016-05-02_124240

You don’t see any Controllers, Models, Views directory here, because we don’t need it. But you can create them for your plugin, for you’ll definitely need them.

You should use NuGet to install following required packages to your project.

  1. EntityFramework
  2. AutoFac

You should also add references to Nop.Core, Nop.Data and Nop.Services to your plugin. Needless to say, set the output directory of your project build to ..\..\Presentation\Nop.Web\Plugins\YourPluginNamespaceName\ (or whatever the path to your plugins directory is). Of course you know that 😛

Step 2: Create the entities

We create entities required by our plugin. For simplicity, we create one entity called EfEntity in the folder Domain. So in the file Domains\EfEntity.cs, include the code below.

Step 3: Create necessary configuration maps

Next we create the entity map for our entity. So open the file Data\EfEntityMap.cs and include the following code. It’s fairly straightforward if you have followed nopCommerce documentation.

Step 4: Create Database Context

Now that we’ve entities and entity maps setup, we need a database context that’ll create the database structure for us. So open the file Data\EfMigrationsObjectContext.cs and use the following code in it.

Notice that we don’t write anything in the Install method. This is because we won’t be executing database tables creation queries directly. Instead, we’d ask Entity Framework migrations do that job for us.

Step 5: Setup Migrations

So far we just did what needs to be done for basic setup of every nopCommerce plugin that uses database. Now comes the interesting part. Because we won’t be using default nopCommerce’s default ways of installing and uninstalling database tables, we’d be needing migrations in place.

For setting up migrations, we’ve manually created a directory called Migrations and created two classes Configuration and MigrationsContextFactory. These two files control the installation and uninstallation of our database tables.

In the Migrations\Configuration.cs file, paste the following code.

And in Migrations\MigrationsContextFactory.cs file, paste the following.

But what is that?

Well, these two files tell EntityFramework about the configuration of the migration that our plugin will be performing.

Configuration.cs

This class simply inherits DbMigrationsConfiguration. That’s generic class  that accepts a generic parameter for a class that inherits DbContext for our plugin. For us, it is EfMigrationsObjectContext class.

Note, how we set TargetDatabase in the constructor.

This is required, otherwise for some weird reasons, EntityFramework starts looking for SqlCompact database.

MigrationsContextFactory.cs

We create this database context factory, so that EFMigrations when queries for a database context, instantiates the database context with appropriate database connection string. Because by default, DbContext can be instantiated with a parameterless constructor, we specifically ask our migrator to instantiate our plugin’s database context with connection string.

Step 6: Run the migrator

Oh yes, we need to do that as well. Because we don’t want the store owner to have to run any upgrade commands or scripts, we’ll need migration code to automatically execute when plugin is loaded. There are a couple of ways of doing it. You can run that code using a IStartupTask provided by nopCommerce. You can also call migrator at any place that runs on application startup.

For our case, we call this in DependencyRegistrar.cs. This is because nopCommerce calls the Register method of IDependencyRegistrar at application startup and so it’s guaranteed to be called every time the application restarts.

So open DependencyRegistrar.cs file and paste the following code.

Notice the code in bold. We check if the plugin is installed and then instantiate and run our migrator. The migrator.Update()  method updates the database with all the pending changes.

Step 7: Build and Install the plugin

Now build the plugin and if you are getting any errors (are you? :o), then something must be wrong with your keyboard or your code :D, Please recheck and try again. Once the project builds successfully, login to your nopCommerce admin and install the plugin.

2016-05-02_122724

Tip:  If you can’t see the plugin, don’t hesitate to click on Reload Plugins button.

Now check the database and you should see your entity tables created.

2016-05-02_122838

Because we’ve used migrations to install the plugin, a __MigrationHistory table will also be created (if it doesn’t exist of course). Open this table to see an entry with the migration namespace that we setup above in step 5.

2016-05-02_122944

Step 8: Check if modifications to entities are correctly applied

Now that we have installed the plugin (or your client has installed it on his server), we need to check if any changes made to entities will be automatically applied to database or not.

We’ll add two columns to our EfEntity.

And to its EfEntityMap as well.

Now rebuild the plugin and restart the nopCommerce application. This is required because we want all new dlls to be loaded by nopCommerce.

If you have a successful build, go and check your database table again and you should see the updated database structure.

2016-05-02_123610

Also if you see __MigrationHistory table, you’d see a new row with the updated migrations data.

2016-05-02_123628

Awesome, isn’t it? So now you can keep your worries of database upgrades aside and create automatically database up-gradable plugins for your nopCommerce.

Wait, what if I uninstall the plugin?

Of course when you uninstall the plugin, all the tables of your plugin should be removed isn’t it? That’s what happens right now. If you see the code of  Data\EfMigrationsObjectContext.cs in step 4 above, you’ll see the following uninstall method.

Here, we instantiate a migrator and call the Update()  method with parameter “0”. This tells EntityFramework migrator to revert to the initial version of the database associated with particular database context.

Cool isn’t it?

Automatic EFMigrations NopCommerce Demo Source Code (142 downloads)