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
Related
I've got an Entity Framework 6 application. I've ported the database from SQL Server to PostgreSQL. Now when I run the application I'm getting this error:
The model backing the 'ApplicationDbContext' context has changed since
the database was created. Consider using Code First Migrations to
update the database (http://go.microsoft.com/fwlink/?LinkId=238269).
The only thing is that the database schema shouldn't have changed. If it has, there is something wrong with my port which needs fixing. I do not want to run a migration to bring the database up to the new version. I want to find out what the change was that has caused this so that I can correct it.
Does anyone know how Entity Framework decides whether the database is out of date and what causes it to raise this error?
Entity Framework stores migration history and the state of your database model in a table called MigrationHistory.
This document has details on customizing that table.
I suggest not modifying this, however. Instead, as a workaround, you can add a new migration, delete whatever content is inside of the Up() method, and then update your database. This will update the history to match what you currently have.
However when you add the migration, you may want to review the code it produces first to see what EF thinks has changed. It might actually be a legitimate migration.
Edit:
Schema changes are compared against hashes of your SSDL.
I am working on a project which is using Entity Framework code first for its data structure. It was created with code first, but was never migrated again and only has its initial migration data stored. Since then, the database has been modified directly through server explorer in VS2015.
There is no migration information about any changes and the database has critical information which I cannot lose.
Which brings me to my Questions.
If I create a new migration and update the database from it, will it wipe all changes which were not recorded in migrations and still leave the changes which were made as well?
The details of your question is a bit sketchy, but I will make some assumptions in order to help you along. Please correct where I am wrong.
I assume that you want to keep the data which resulted from the changes which were effected directly to the database, but you do not want to keep the changes that was effected to the database - in other words: keep the data but not the datastructures.
My advice is as follows
Always perform a full backup of your database when you are about to do something you are uncertain about.
If you can identify the tables you want to update, you can always use the SELECT INTO statement to create a quick backup of the specific tables only. These tables will not be removed when you do a EF database migration unless you explicitly script the deletion.
You can build the SELECT INTO statement into your EF migration via the Sql() method, or you can manually run the command against the database.
More information:
Click here to learn about EF code first migrations in general
Click here for a comprehensive code first migration reference
I believe following two posts will help you.
EF 4.3 Migration Walkthrough : http://blogs.msdn.com/b/adonet/archive/2012/02/09/ef-4-3-code-based-migrations-walkthrough.aspx
update:
Code First Migrations with an existing database
https://msdn.microsoft.com/en-us/data/dn579398.aspx
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 redesigned my class scheme many times since started the project I'm working on.
At first I didn't know about data annotations, so I have migration1, where my Ids have no DatabaseGenerated.Identity option and migration4 where they already have it.
Turns out that EF doesn't work this way (https://entityframework.codeplex.com/workitem/509 as for EF5), so when I added some seed data, it threw an exception
Cannot insert the value NULL into column 'primarykeycolumn', table 'tablename'; column does not allow nulls. INSERT fails.
What's really interesting is when I deleted all existing migrations and scaffolded new one from scratch, seed method ran without any problems.
So I have a question: do I need to do it any time I make changes to scheme such as adding data annotations like Identity or is there a way to save my previous migrations? Because dropping and recreating db in real-life can result in a huge data loss, which I want to avoid.
Adding Migrations. In your Package Manager Console
Add-Migration Test1
In your Configuration.cs from Migration Class You will see Up method and Down Method. It is like Before, and After Changes. You can call them up if you want to reverse the Changes.
doing Add-Migration "NameoftheMigration" does not implement it
you need to call
Update-Database
If it tells you that there is an error, or potential Data lost.
Update-Database -Force
If you choose to use CodeFirst. You can't really Jump from Altering table by Design, then by code. You have to Choose one. As CodeFirst Migration rely on Models. Data First, Rely on Data Design.
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.