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?
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:
Add-Migration
to create the migration for the changes. (This creates the hidden IMigrationMetadata.Target
value.)IMigrationMetadata.Target
values is now out-of-sync.)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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With