Getting Your Database Back in Sync With Your Entity Framework Code First Model

I've been playing with Entity Framework 5 and Code First for the past few days. At some point during development of a new application I needed to update my model but could no longer afford to let the app just drop and re-create my database for me because I input a bunch of data that I didn't want to lose. My only good option was to enable entity framework migrations. I ran into a bunch of problems getting migrations working and as part of my attempts to solve the problem I ended up deleting dbo._MigrationHistory thinking that would allow me to start fresh with enabling migrations, making the application unaware of an previous migration attempts. My real problem turned out to be that migrations were updating a local MDF file while the app was pointing at the remote database, but that's a post for another time.

Once I had my web.config connection string configured correctly I enabled migrations fresh in my app. It looked at the connection string, found my database, and enabled migrations just fine. All was well until I tried to add-migration. It kept generating a database initialization script. Basically, it thought the database was fresh and that it needed to create all the tables. This was because I foolishly deleted the migrations table in my database without thinking. I tried running the script knowing that it wouldn't be able to create tables that already exist, but as I suspected it failed at that point and discontinued the script.

I scratched my head for about an hour until I found this little beauty:

update-database -script

That little command generates a SQL script to update the database instead of actually trying to update the database itself. After generating the script it was simple. I removed the bits for adding tables, foreign keys, etc etc (the stuff I already knew existed in my database). I just left the part where it created the _MigrationHistory table. I executed the script on my server and it worked! Migrations were back in sync with my model again. Running update-database would no longer try to run the initialization script because the metadata in the table we added let it know that it had already been run up to that point. I am now able to modify my code first model and run add-migration to generate proper migrations.

Hopefully this helps others in the future with the same problem.