We are using Entity Framework code first migration technique for a while now. Everything works good however our Migrations folder has been growing big with numerous migration files because of changes we are making on entity schema. I was curious, is there a way we can update just one or specific number of files whenever there is change in entity so that our Migrations folder would look less messy. Also, i don't want to drop the table and recreate it since i will be loosing all the saved data.
You could simply merge all of your migrations into a new file (if you aren't concerned with keeping every migration).
To do so, simply delete every migration currently in the folder, and rerun the enable-migrations command and then the add-migration command like so.
Enable-Migrations
add-migration InitialCreate
You can try to use database initializer called MigrateDatabaseToLatestVersion. That automatically updates the database schema, when your model changes without losing any existing data or other database objects.
Database.SetInitializer(
new MigrateDatabaseToLatestVersion<YourDbContext,
DataLayer.Migrations.Configuration>());
Related
I renamed a few tables and some columns. When I run the Add-Migration command, the migration generates code that drops the old tables and columns and adds ones with the new names. This results in losing the data they contained.
Since I don't want to lose the data, I want to edit the migration, removing the drop and add commands, and replacing them with rename commands.
But after I edit a migration, how do I apply that change?
If I run the Update-Database command, that applies it to the database. But not to the snapshot that Entity Framework maintains of my schema (stored in ApplicationDbContextModelSnapshot).
I need a way to incorporate my edits into the model. How can I accomplish this?
So, this is definitely the messy part of code first.
As far as the question asked, as GuruStron suggested, the only way I found to have a valid custom migration is to edit it such that the result is the same as what the original, generated migration produced. This keeps it up to date with the database snapshot. And running Update-Database will run your custom update code.
I think my biggest problem was that I had too many changes going on at once. After struggling with this for a while, I undid some of my changes and added them back bit-by-bit. Entity Framework will rename a table or column if it can figure out that the new name refers to the same column. If it finds many changes, it can't figure this out.
In the end, I had to customize the migration a little for a couple of columns that were being dropped (customized them to be renamed instead). But I was able to get Entity Framework to rename my tables and other columns.
The key: make small changes at a time and carefully review the migration before applying them to the database. If you need to customize the migration, do it such that the end result doesn't change.
You don't.
I suppose you are developing using a code first approach, since the question has this tag on it.
If you are using code first, you must change your models and let Entity Framework change the database schema for you.
Suggested reading:
Migration in Entity Framework Core
Entity Framework Core Migrations
I am using EF code first to create my database, the application is in production and test now so I need to run migrations to update the database as my model changes.
I have set up migrations based on the standard instructions and it works fine, against dev database one. I also have a second database that I want to bring in line with the current code base but this second database is in an unknown state.
What I want to know is can I generate a migration class against a different database and how do I do that? I can't seem to generate a migration class against anything other than the original database I specified when I set up migrations. I have changed the DB name in the app.config but it still looks at the original database when doing migrations.
How can I explicitly specify which database to generate the migration script against?
Migrations don't look at the database other than to check if a migration has been applied (__MigrationHistory). When you setup migrations it takes a snapshot of the code models and uses that when moving forward. So if you want to bring a database in an unknown state under migration control you will need to get it to match the code model.
You could do something similar to this: Create an idempotent script from your current database (update-database -Script –SourceMigration $InitialDatabase). This will be the equivalent of all migrations needed to create and bring your database current. Since you have an existing database where some of these objects exist, you will need to manually adjust the script by removing the code for items that already exist. Once you get it to apply, you should have a database that matches your model with a populated __MigrationHistory table.
Another option is to use a schema compare utility to make the databases match and then just copy the __MigrationHistory table over.
See Migrations Under the Hood.
I'm using EF 6.0.0 and .Net 4.5.
I face a very confusing problem. Me and one of my colleagues are working on the domain model section of our project on two different clients. The problem is:
1- Me and my colleagues start with the absolutely identical project and we are completely synced with the source control.
2- When I change the model for example add a property then Add-Migration FromA then Update-Database it works great. The generated code file contains just one command that is to add the column.
3- Meanwhile, after the db is updated and just before I check in something to source control, my colleague adds another property and then Add-Migration FromA then Update-Database. And guess what? This generated code file has a command to drop the column I newly added!!!
I added another column using native Sql, and fortunately the column is not going to be deleted.
I deleted the __MigrationHistory table and the remove column didn't get generated.
I turned off initializer Database.SetInitializer<MyContext>(null), no success.
So, my guess is that EF Migrations compares current model with the last one stored in __MigrationHistory table not the last local snapshot stored in .resx file. Am I right? Any way to solve the problem?
I have several migration files in my project and since I made manual modifications to my last migration I don't want to re-generate it with the "package manager console". I only need to add 1 column. So Added this manually a previous migration (I can do this since no-one has upgraded yet).
Now, when I start my project, the local database seems to create my new column fine but I do get an exception:
"Unable to update database to match the current model because there are pending changes and automatic migration is disabled"
It looks like the only way I can solve this is to generate an extra migration - even though, this migation generates exactly the same line of code that i wrote manually in a previous migration...
I was wondering - how does EF keep track of this and is there a way to bypass it ?
Also another question - is it wrong of me to want to limit the amount of migration files that I have ? I currently feel that in an ideal situation each Release of my software should only have 1 migration file at most in order to keep a better overview of my code...
thank you,
EF saves a hash of your serialized Model in the _MigrationHistory table, and compares them when you use migrations to ensure the database schema matches the model. I do not advise trying to bypass this. If you wish to mimimise the number of files then you can rollback then combine the migrations. But I don't think it's worth it. I just put my migrations into sub-folders periodically
I recommend this article:
http://elegantcode.com/2012/04/12/entity-framework-migrations-tips/
Check the table called _MigrationHistory in your Database. This will have the history of migrations you ran.
I don't think single migration is such a good idea. Because:
Each migration is like a version of the Database. You can go back to any version by doing "update-database -target migration MigrationName".
If many people are working on the project, it will become very difficult to keep track of what version is your DB is in and it will get messy.
If you want to add an extra column you can -force it to previous migration. Otherwise it is better to have multiple migration to avoid the confusion.
I have a downloaded production database with an empty MigrationHistory table (contents were accidentally deleted).
I have an updated code model in my development environment (with no previous migrations).
In other words, there's a mismatch between the downloaded production DB schema and the dev environment code model -- and no history between them.
How do I scaffold a code-first migration (or get the SQL) to update the production database to the new model?
I have tried the following, as per the suggestions here:
Enabling migrations in my project (Enable-Migrations)
Adding an empty migration (Add-Migration InitialCreate -IgnoreChanges)
Applying this migration (Update-Database)
This results in a row being added to the MigrationHistory table.
However, EF seems to think that this means that the current code model matches the database schema (which, of course, it doesn't).
If I try adding a new migration (Add-Migration UpdatedModel), this migration comes out empty, which it shouldn't since the code model and the database do not match.
How can I get a code-first migration (or the SQL) that reflects the changes between the code model and the database schema? (If I try doing Add-Migration InitialCreate without the -IgnoreChanges flag I get the whole database created from scratch, correctly reflecting the code model, but I want the changes.)
The first step in the guide you're following clearly says that you need a model in sync with the DB. That0s wat it's failing.
What you need to do is:
temporarily delete the current Code First model (i.e. back up the files of the current model somewhere: file system, CVS)
reverse engineer the Code First model from your existing DB
enable migrations, and create the initial migration: Enable-Migrations
At this step, you have your DB and model in sync. A few more steps and you're ready to go:
Replace the model with the original one (the one you kept in the previous step 1)
Add a new migration Add-Migration
Update your DB: Update-Database
Tchan! You've got it! By the way, it's important to understand each parameter of the migrations commands, to do so, in your Package Manager Console, use any of this commands:
get-help Enable-Migrations -examples
get-help Enable-Migrations -detailed
get-help Enable-Migrations -full
In few words: when you enable migrations, the Code First model and the DB must match.There is no other way to do it. That's why you must reverse engineer the DB to get the initial synchronization, and work from this point on.