Edit: I dropped the database. It still tells me the migration is applied. I don't buy your shit, EF...
I have 5 migrations, but the 5th has been created on accident. It doesn't hold any changes (Up and Down methods are empty). Without thinking I appied it to the database.
Now when I run dotnet ef database update migration4 it tells me it successfully reverted migration #5 and the table __EFMigrationsHistory doesn't show an entry for migration #5. Upon trying to remove it with dotnet ef migrations remove it tells me that migration #5 is still applied to the database and the entry in __EFMigrationsHistory shows back up.
When rolling back to migration #3 with dotnet ef database update migration3 it does remove the changes from migration #4, and removes the entries from the __EFMigrationsHistory table.
Now, when trying to remove, it just reapplies all the migrations. Same for reverting back to initial migration.
Any suggestions? I have no idea where to begin. Do I have to redo the whole database and/or migrations? I tried overriding migration #5 but dotnet ef migrations add doesn't accept the parameters -f or --force.
the better way is
go to
PM Remove-Migration
PM Drop-DataBase
or delete your migration folder in your solution explore and create a new migration
this will make your all 5 migration into one migration
PM Add-Migration
PM Update-Database
Related
Environment: .NET Core 3.1 with EF Core
Short story: two migrations (A and B) were made. B is based on A. But update-database has not been executed for both A & B. A was deleted. Is there a way to revert A & B?
Long story: I think I did something stupid. I added a class in the code, then did add-migration (let's say it's migration A). After inspecting the generated migration class, I went back to make some changes. Because I haven't run update-database yet, I deleted migration A, then ran another add-migration, got migration B. Then I found out B is based on A. Deletion of migration A doesn't clear the migration.
Further research I found the migrations, even not updated to database, are kept in the MyDBContextModelSnapshot.cs file. Is that's how EF keeps track of it? I can't run update-database now because migration A is missing. Applying migration B will just cause an error in database.
My question is, instead of going into MyDBContextModelSnapshot.cs and manually revert it to before migration A and redo a migration, is there a way to fix this problem?
Thank you.
After some research, I simply executed this command to remove both A & B, even though the migration file of A has been deleted (and I didn't find it in recycle bin).
Remove-Migration
Then by using "add-migration" ef core created correct migration script.
Thank you.
The problem is indeed in the snapshot file, and you need to revert it to its state before A was added. Then you can add B and it will create all the new changes that were previously in A. This should do the trick even without the migration files:
dotnet ef database migrations remove B
dotnet ef database migrations remove A
dotnet ef database migrations add B
If it throws errors and you have source control this should also be a quick revert, if not, you should setup source control to prevent this type of thing. Committing early and often is a good practice for individual developers as well as teams, and it makes undoing mistakes trivial.
Finally, if the commands don't work and you don't have an earlier copy, you can use a previous migration. If you had a migration Z before adding A, you can copy the content of Z.Designer.cs to the snapshot (don't change the class name or imports). The migration designer is how EF tracks the changes, and it is applied to the snapshot when the migration is added. This is the same as manually reverting the snapshot, but less chance for error.
We have a EF project with multiple migrations being applied almost weekly to our database. I have to remove and add a new migration because I made a typo in a property of a model and I need it to be re-created.
I followed the usual steps:
dotnet update database MOST_RECENT_CORRECT_MIGRATION -c CONTEXT_NAME
dotnet ef migrations remove
The last command should revert model snapshot changes and delete the migrations cs and designer.cs files, but instead it only reverts the model snapshot and it doesn't deletes the previous migration. Until a few migrations back it worked perfectly and I was able to follow this workflow and recreate migrations that needed naming changes and more from the PRs. I can delete the migration manually and try to come up with a working new migration but I don't want to break things in the background and I want to do things properly.
When I run it with verbose I get (among the usual enormous amount of messages) the following message that looks not good:
[...]
A manual migration deletion was detected.
[...]
Does this have anything to do with the problems I'm having? Should I just delete all the changes and recreate a new migration from, say, the last moment it worked fine?
I'm using .NET Core 3.1 and SQL Server.
I can also move on a create a new migration that drops the wrongly typed column and replaces it with the new, correct one.
Let's say I have a database which is created by three migrations. They can be seen in the table dbo._EFMigrationsHistory and the content could look like this:
MigrationId ProductVersion
20200516181941_InitialMigration 3.1.4
20200517091058_AddedIndexes 3.1.4
20200605115456_IntroducedBreweries 3.1.4
Now let's say that I for some reason lose all of the table (or just a part of it). So suddenly the table look like this:
MigrationId ProductVersion
20200517091058_AddedIndexes 3.1.4
20200605115456_IntroducedBreweries 3.1.4
And then I make a new migration, because i changed something in the database
Add-Migration SomethingChanged
This will work fine, since we aren't talking to the database at this point. But if I try to update the database, like this
Update-Database
It will fail, because it it trying to re-run the InitialMigration (or at least so I assume). So a common error is that the tables created in the InitialMigration cannot be created, because they already exist.
During development you can simply nuke the database and/or migrations, but that's not a very viable strategy for production. It can also be done with Script-Migration, which has a from/to option, allowing something like this:
Script-Migration 20200517091058_AddedIndexes 20200605115456_IntroducedBreweries
But this doesn't seem to work on Update-Database (not in the documentation either).
Is there any (production safe) way to fix this, so that the migration history isn't broken for all eternity?
The best way I can think of, is to manually insert the missing row(s) in the database, but this seems quite hack-ish...
The Issue: You have mucked up your migrations and you would like to reset it without deleting your existing tables.
The Problem: You can't reset migrations with existing tables in the database as EF wants to create the tables from scratch.
What to do:
Delete existing migrations from Migrations_History table.
Delete existing migrations from the Migrations Folder.
Run add-migration Reset. This will create a migration in your
Migration folder that includes creating the tables (but it will not
run it so it will not error out.)
You now need to create the initial row in the MigrationHistory table
so EF has a snapshot of the current state. EF will do this if you
apply a migration. However, you can't apply the migration that you
just made as the tables already exist in your database. So go into
the Migration and comment out all the code inside the "Up" method.
Now run update-database. It will apply the Migration (while not
actually changing the database) and create a snapshot row in
MigrationHistory.
You have now reset your migrations and may continue with normal migrations.
I have two solutions, the base solution with no migrations(which is in production, so I can not wipe the data) and now I have branched of this to set up migrations and make some model changes.
First I need to set up migrations on the branched solution (second solution) so that I can apply the model changes so I:
Turn on migrations which auto creates an InitialMigration
Enable-Migrations -ContextTypeName Context
Make a blank migration based on the suggestion from https://www.apress.com/gp/blog/all-blog-posts/secular-trends-for-the-cloud/12097630
Add-Migration InitialBlank -IgnoreChanges
Update Database * update-database*
Make my model changes
Add a migration containing my model changes * Add-Migration add_entity*
Run Update-Database
So I delete the database created as I need to run the first solution to create the initial db setup (to mimic live).
When I run the first solution it creates an entry in MigrationsHistory table named InitialCreate (201807061432030_InitialCreate), which has been auto created. I then run update-database on the second solution which applies my model changes fine although their are discrepancies in the InitialCreate MigrationId.
Migration entries in my second solution (in order they were created and the order they are in the solution):
- 201807061257015_InitialCreate
- 201807061315294_InitialBlank
- 201807061323086_add_entity
Migration entries in the migration history table after running the first then second solution:
1 | 201807061315294_InitialBlank
2 | 201807061323086_add_entity
3 | 201807061432030_InitialCreate
The second solution runs fine but when I try to add any data I get System.InvalidOperationException: 'The model backing the 'Context' context has changed since the database was created. Consider using Code First Migrations to update the database.
I have tried to create another migration on the second project to make sure their are no model changes that have not been migrated (their shouldn't be) but I get an error.
Unable to generate an explicit migration because the following explicit migrations are pending: [201807061257015_InitialCreate]. Apply the pending explicit migrations before attempting to generate a new explicit migration.
My questions:
How do I resolve the MigrationId mismatch? As the first solution did not have migrations turned on and when I do turn them on (in the second solution) it creates a new id.
Could the exception System.InvalidOperationException: 'The model backing the 'Context' be thrown by the MigrationId mismatch or could anyone point me at why this could be happening? I have had a look into this error but the solution's I found don't seem to work:
Deleting the migrations history table is no good as I can not do this in production because of customer data.
The other solution I found of adding Database.SetInitializer(null); to global.asax seems to make no difference.
Why does the order of my migrations look different once they have been applied in the migration history table?
Thanks in advance!
I am not sure if this will work but I think I may need to manually delete the first InitialCreate and edit the db entries to reflect the correct InitialCreate. Based of this SO question I just found https://stackoverflow.com/a/13108243/3172635.
I will have to try this Monday though.
Edit: I first tried deleting the InitialMigration entry in the _MigrationHistory table but this does not work as it tries to apply the InitialMigrations again but cant as the tables are already created. So what I did was update the MigrationId for the InitialMigration entry to reflect what it was in the new project.
The sql I used:
SET MigrationId='201807061257015_InitialCreate' WHERE MigrationId = '201807061432030_InitialCreate'
I'm using code first migrations. Is there a way to display pending model changes in package manager console before I scaffold a new migration?
The accepted answer tells how to get the SQL for a already scaffolded model change before applying to the database.
The original question regarded model changes pre-scaffolding (i.e. changes in the model since the last "add-migration" before running the next "add-migration" ...)
To that answer i will just say: scaffold anyway, that gives you your preview. By that i mean, run "add-migration preview" or something similar, it will create the scaffolded migration with the model changes that you are interested in. Then just delete if from your solution ...
The point here is that there is no need to "preview" when actually "doing" can be quickly undone. Some might think deleting a scaffolded migration version from the migrations section of the solution would break something, but no it is very well supported.
You can even test scaffold, then create the sql script as Colin suggest in his answer, to get the full SQL. Still nothing has been done at this point, so delete the migration version if you'd like.
There is no way that I know of to view pending changes in the model before scaffolding the migration, but I can't think of a reason not to scaffold the migration using Add-Migration so that the pending changes can be viewed in the migration file. There is no need to apply those changes to the database and the scaffolded migration can always be deleted.
Once the migration is scaffolded, if you use Update-Database -Script entity framework generates a SQL script rather than executing the changes directly.
You can get help on the EntityFramework in the package manager using get-help EntityFramework
And you can get help on the Update-Database command using the following:
get-help Update-Database
get-help Update-Database -detailed
get-help Update-Database -full