14

My model contains, among other things, two properties that were added to the model class after its initial creation and migration.

public sealed class SomeModel { ... other properties, which are fine. public int PropertyOne { get; set; } public int PropertyTwo { get; set; } } 

My most recent migration contains:

public override void Up() { ... other table being created. AddColumn("dbo.SomeModel", "PropertyOne", c => c.Int(nullable: false)); AddColumn("dbo.SomeModel", "PropertyTwo", c => c.Int(nullable: false)); } 

The target database contains the PropertyOne and PropertyTwo columns, and the __MigrationHistory table contains entries for both the migration that created the table and the migration that added the columns.

When I run Add-Migration to get some other changes, it also includes those two properties again:

public override void Up() { ... other changes. AddColumn("dbo.SomeModel", "PropertyOne", c => c.Int(nullable: false)); AddColumn("dbo.SomeModel", "PropertyTwo", c => c.Int(nullable: false)); } 

What could be causing this? I also notice that if I revert all of my model changes and try an Update-Database (which should do nothing), I get the error:

Unable to update database to match the current model because there are pending changes and automatic migration is disabled. Either write the pending model changes to a code-based migration or enable automatic migration. Set DbMigrationsConfiguration.AutomaticMigrationsEnabled to true to enable automatic migration.

What could be causing this?

2 Answers 2

24

As it turns out, there is a hidden snapshot of your model in the .designer.cs class associated with your migration. (This is IMigrationMetadata.Target, and is not human-readable.) The series of steps that caused the problem were:

  1. Create changes to the model.
  2. Run Add-Migration to create the migration for the changes. (This creates the hidden IMigrationMetadata.Target value.)
  3. Noticing that there are errors in the way the migration was modelled, change the model class and migration class directly. (The IMigrationMetadata.Target values is now out-of-sync.)
  4. Run Update-Database to apply the changes.

To get out of the mess, create a dummy migration using Add-Migration Dummy, then delete everything from the Up() and Down() methods.

Note that Add-Migration does warn you about this; when you run Add-Migration, it displays:

The Designer Code for this migration file includes a snapshot of your current Code First model. This snapshot is used to calculate the changes to your model when you scaffold the next migration. If you make additional changes to your model that you want to include in this migration, then you can re-scaffold it by running 'Add-Migration Dummy' again.

The warning just didn't make any sense until I figured out what the problem was, and saw the hidden IMigrationMetadata.Target value.

Bottom line: don't manually keep your model and migration Up() methods in sync; you have to re-run Add-Migration to set the hidden value correctly.

Sign up to request clarification or add additional context in comments.

5 Comments

Excellent answer; very hard to find. Thanks for posting.
FYI: The Target data in the resource file is a bas64 encoded, gzipped, edmx (xml) file.
Thanks for providing this information. It certainly explains why the EF can be so difficult to work with when you need to modify relationships and cannot fathom why it's doing some of the things it's doing in the migration.. Abandoning code-first migrations is increasingly appealing :)
@mattpm, FWIW, I have abandoned not only code-first migrations but EF entirely, and am loving it. The "ease of development" was largely elusive, and I got tired of the hard-to-debug "magic" that was happening and the crappy SQL that was generated. I have found much better success with light-weight ORM such as Dapper. YMMV.
@wischi Where is this magic Taget file located? I've deleted everything and my Add-Migration still magically has a cache somewhere.
0
  1. Copy the migration code into notepad or some text editor
  2. Delete your problem migration that is not working
  3. Add-Migration YourMigrationName
  4. Paste in your migration code that is held in your text editor
  5. Update-Database

This is kind of an ugly work around in my opinion, but it is the only way I have found to make sure my migration has all the changes in it. My guess is Entity Framework makes a migration stale after a certain amount of time so you have to create a new one.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.