0

I'm writing a web api attached to a database that I created using Model First.

Being new I was confusing Model First with Code First.

As it's my first EF/Web app I didn't realize that migration wasn't yet implemented by Model First and I followed the procedure to implement it. When it ran I received some errors, looked them up and only then realized I'd need to remove it again.

Following somebody's instructions I deleted the migrations folder, plus the _migrationHistory table from the database.

But now I receive the following exception whenever the _migrationhistory table is missing from the database.

protected void Application_Start()
{
  // Call initializer
  Database.SetInitializer(new PulseDbInitializer());
  new ApplicationDbContext().Database.Initialize(true); <- error here

  AreaRegistration.RegisterAllAreas();
  GlobalConfiguration.Configure(WebApiConfig.Register);
  FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
  RouteConfig.RegisterRoutes(RouteTable.Routes);
  BundleConfig.RegisterBundles(BundleTable.Bundles);
}

"An exception of type 'System.NotSupportedException' occurred in EntityFramework.dll but was not handled in user code Additional information: Model compatibility cannot be checked because the database does not contain model metadata. Model compatibility can only be checked for databases created using Code First or Code First Migrations."

The following is a partial description of my initializer

public partial class PulseDbInitializer : DropCreateDatabaseIfModelChanges<ApplicationDbContext>, IPulseDbInit
//public partial class PulseDbInitializer :DropCreateDatabaseAlways<ApplicationDbContext>, IPulseDbInit
{
  private ApplicationDbContext _context;
  protected override void Seed(ApplicationDbContext context)
  {
    _context = context;
    var pid = new PulseDbInitializionData(context);
    pid.Init(this);
  }
}// class PulseDbInitializer

It seems that the app is trying to use migrations (because it's creating the _migrationhistory table) even though I've removed the migrations subfolder. Being new at this, I'm not sure where to go. I'm aware that I've created my initializer, see above, so am I missing something?

EDIT - Too long for a comment

Im not sure we're understanding each other.

Very simply, I don't know what's generating the _MigrationHistory table in my database as afaik if I remove the Migration subdirectory from my project and delete the database, then I thought that's all I need to do to drop migrations.

In my model first, the DropCreateDatabaseIfModelChanges is what I've always used for generating the database and is working as expected. It creates a new database, or recreates when the model changes.

Until I added the migration I didn't notice this _MigrationHistory table and I don't have a clue if the add-migration command added any code to my project that I need to delete or change (I really hate things happening and not being told exactly what was done in some kind of log. Please microsoft, for future reference)

Or am I totally wrong and the _MigrationHistory table was always there but I never noticed? It all seems to work, as long as I don't remove the table.

Czeshirecat
  • 497
  • 1
  • 3
  • 16
  • The DropCreateDatabaseAlways that you have commented out should work. http://stackoverflow.com/questions/29349443/why-model-compatibility-cannot-be-checked – Steve Greene Apr 18 '16 at 13:12
  • @SteveGreene yes, but that'd drop and recreate the database on every initialization, wouldn't it? – Jcl Apr 18 '16 at 15:59
  • Yes, run it once then switch back to DropCreateDatabaseIfModelChanges – Steve Greene Apr 18 '16 at 16:48

1 Answers1

0

Your initializer is inheriting from DropCreateDatabaseIfModelChanges, which checks for model changes. Since you are not using code first you can't check for model changes in code (since your code doesn't define the model -that'd be code-first-... the model defines the code -that's model-first-)... so you need to implement your own IDatabaseInitializer which only checks (for example) that the database exists:

public partial class PulseDbInitializer : IDatabaseInitializer<ApplicationDbContext>, IPulseDbInit
{
  public void InitializeDatabase(ApplicationDbContext context)
  {
    var exists = new DatabaseTableChecker().AnyModelTableExists(context.InternalContext);
    if (exists == DatabaseExistenceState.Exists)
    {
       // maybe check if certain data exists and call the `Seed` method if
       // it doesn't
       return;
    }

    // Throw some error if it doesn't exist
  }

  protected override void Seed(ApplicationDbContext context)
  {
    _context = context;
    var pid = new PulseDbInitializionData(context);
    pid.Init(this);
  }
}
Jcl
  • 27,696
  • 5
  • 61
  • 92