Code First Migrations for a custom NuGet package can't be executed from main application

code-first ef-migrations entity-framework

Question

I have created a module to be included in a main MVC3 web application. The module is packaged into a NuGet package and it can be installed and uninstalled via NuGet. Both, the main site and the module use Code First, EF >= 4.3

To create the package I have another MVC3 site and all the functionality is inside an area, so to create the package I just pack the libraries, the views and all the needed files. Database Migrations work fine in the project and the package is created nicely.

Now I install the package in the main site via NuGet. This site is in another solution, and the solution has two projects:

  • MyProject.Web.UI: this is an Mvc3 project
  • MyProject.EntityFramework: this is a class library with all the models, dbContext for MyProject...

The package is installed correctly and the Area, the Area views and libraries are correctly installed.

The problem now is how I update the database? I've tried first to run "Update-Database" but I get the message:

"No migrations configuration type was found in the assembly 'MyProject.Web.UI'. (In Visual Studio you can use the Enable-Migrations command from Package Manager Console to add a migrations configuration)."

I've tried then to enable the migrations with "Enable-Migrations" but I got this other message:

"No context type was found in the assembly 'MyProject.Web.UI'."

I tried also just to run the site and see if the changes are automatically applied but I get the exception page with the typical message:

"The model backing the 'NugetPackageDbContext' context has changed since the database was created. Consider using Code First Migrations to update the database"

I don't know what to do to update the database with the required changes in migrations that come in the NuGet package. Any one could put some light here in this matter? I'm quite new to Migrations, maybe there are some configs to update the database if there is a change instead of running the commands in the console, I'm a bit lost.

Thanks in advance :)

1
5
9/27/2012 3:29:01 PM

Accepted Answer

Good news! It seems that I got it. I was looking for a way to make the NuGet package to update the database to the latest version.

Well, this package comes with an Admin controller, so I added a new action called Update:

public ActionResult Update()
    {
        System.Data.Entity.Database.SetInitializer(new System.Data.Entity.MigrateDatabaseToLatestVersion<MyPackageDbContext, MyPackage.Migrations.Configuration>());
        return View();
    }

In my Configuration class for the migrations I have:

public Configuration()
    {
        AutomaticMigrationsEnabled = true;
    }

I have to say that in my way to do all of this I've found a few strange behaviors. One thing that surprises me is this, I don't know if this is normal, read the secuence:

  1. Package installed with new migrations but database not up to date. So if I access the EF this affected by this I get the exception about this. Ok up to this.
  2. I go to my action /MyPackage/Admin/Update and run it. Apparently it runs. I go to the database and I don't see changes. Even the migrations table does not have a new row.
  3. I access again the EF part that displayed the exception before (point number 1) and then everything goes through, database is updated and the migrations table shows the new line.

One thing that you have to notice is that the Configuration class is internal, but because this is a module I needed to be accessible from another assembly. I tried to make it public but I got some strange warnings/errors that I don't know if they are related. So in the end I kept it internal but used

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("OtherAssembly")]

I've found a few of strange behaviors in Visual Studio with all this stuff of the NuGet packages, CF, migrations ... I don't know if these things are bugs, but all this thing took me two full working days.

I hope it is useful for any other that wants to create a CF NuGet package that is updateable.

2
9/28/2012 2:22:26 PM

Popular Answer

In package manager console you will need to the Default project to MyProject.EntityFramework

You may also need to make sure MyProject.Web.UI is set as the start up project (in case there are multiple), then you can pass in the connection string into update command:

Update-Database -ConnectionStringName MyConnStringName

This should update the database correctly, unless there is data that will be lost.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow