How to Cleanup & generate fresh migration for existing DB? - entity-framework

We wish to get rid of 100s of migration classes as DB schema in production is final.
Here are the steps I followed:
Delete Migrations folder.
Add-Migration -??
What command line switches, could help us?
EDIT:
If all goes well Up() method of migration should be empty right? For
example following is wrong generation on Add-Migration. Because if we
execute the project we will get duplicate table errors.
public partial class Sanity : DbMigration
{
public override void Up()
{
CreateTable(
"dbo.AccountPreferences",
c => new
{
AccountID = c.Guid(nullable: false),
}
.... for 1000s of tables
}
}
A clean migration would be something: when trying Add-Migration on subsequent changes, should not be getting any error.
Unable to generate an explicit migration because the following
explicit migrations are pending: [201712281054591_Sanity]. Apply the
pending explicit migrations before attempting to generate a new
explicit migration.
As you can see if we happen to execute Update-Database will get table already exist error.
Are we forced to always retains all migration copies?

See if this can help:
MVC3 and Code First Migrations - "model backing the 'blah' context has changed since the database was created"
Entity framework code first - how to run Update-Database for production database
How to delete and recreate from scratch an existing EF Code First database
note:
I'm writing this from memory, if you have issues let me know and I'll recheck exactly.
Also, my knowledge on this is from slightly older versions of EF as I haven't done much work there recently, but I doubt much has changed.
From what I can tell, if you want to...
a) keep the db,
b) clean your project migrations,
c) have the 2 'match', be in sync:
do the following:
- Remove the migration folder (your project)
- Run Add-Migration Initial - then should add one migration
- caution: it is safe but do backup, change connection string etc. before the next step
- Run Update-Database -Script - that doesn't update the db but creates the SQL script, including the migration table
- find the INSERT INTO [__MigrationHistory] records, just run those (on your db), insert them into the database
...then test with Add-Migration again, to see if it is going to make anything, should yield no new migrations, empty one.
Please read through the first link above and adjust approach as needed.
I'm sure there might be easier, shorter ways to do this (via PM console) but unaware of it at the moment.

Open your database.
Clear table __MigrationHistory
Remove migrations in the folder
Run Add-Migration MigrationName

Almost the same as accepted one, but no scripting the initial migration.
Drop the __MigrationHistory db table
Remove all the migration files in the Migrations folder
Run Add-migration Initial in Package Manager Console
Comment out the code inside of the Up method in the Initial Migration
Run Update-database in PM Console (just to create a Migration Entry)
Remove comments in the Initial migration

Wonder how long it will be "final" ?
Use:
Add-Migration Initial
After removing the migrations folders

Related

EF Code First Drop Database?

I want to use EF code first migrations to create my models in the database. However, the database I will use already exists and is shared by other applications. My question is:
Do migrations erase the database? That would be a disaster!
Do migrations erase anything at all?
Q : Do migrations erase the database ?
A : No.You can do that without erasing it.
You have to do it as shown below on the Package Manger console.
Step 1 :
PM > Add-Migration InitialCreate –IgnoreChanges
Above command will create an empty migration with the current model as a snapshot.
Step 2 :
PM > Update-Database
Above command will apply the InitialCreate migration to the database. Hence the actual migration doesn’t contain any changes, it will add a row to the __MigrationsHistory table indicating that this migration has already been applied.
You can read more about it here : CF Migrations with an existing database
What I usually do in this situation is create a migration to the existing database and then remove everything out of the Up and Down methods and run the update. This way your code first migrations will be up to date with whats currently in the database so any new schema changes that are made will be the only thing picked up by adding a second migration.

EF 7 Migration to Existing Database

I am working on a web project using ASP.Net 5 and EF7.
I have imported all the tables from existing database onto my models in my project. However, I am having problems in regards with migrations.
I have created the initial migration, made some changes on particular entity, create another migration following the changes I have made and now want to apply the changes on the database.
After running this command below:
dnx ef database update [Migration]
the dnx is trying to apply the 'initial' migration with all the entities which are already in database and this causes an error as below:
{ There is already an object named ['EntityName'] in the database. }
Can you please advise on how to do the migration on the existing database?
Thanks
Saeed
In EF6 you would run a migration with the -IgnoreChanges flag and it would take a snapshot of the model without any Up() code. This is missing from EF 7(EF Core) as indicated here.
The workaround for now is delete or comment out the code for existing database objects from the Up() code of the migration and then update-database. Subsequent migrations will then include only the changes.
After 2 days I found a way for EFCore that is not in google and internet!
How My steps works?
When you have a database with 10 table and you have data in tabales that you don't want to clear's data.and after this you will create new models in your code first and runnig to existing database and you will get error "Invalid object name 'tableName'." for query to new tables and you want to create migrations and do update it to existing database but first migration will create all queries for old and new tables if you run update-database you will get "There is already an object named ['EntityName'] in the database." for your initial migration.
How fix it?
Delete all migrations and snapshot in you database project
Delete __EFMigrationsHistory table in your existing database (if exist)
Run in Package manager console:
Note before run: This code will create new context and models of your existing database to Data folder so don't forgot to check you have not Data folder in your project.
Scaffold-DbContext "your connection string"
Microsoft.EntityFrameworkCore.SqlServer -OutputDir Data
Run in Package manager console:
Note before run: Create first migration for initial database with Data folder context (OldDataBaseContext is inside of your Data folder that created by step 2)
Add-Migration initial -Context OldDataBaseContext
Delete all code in Up method inside of created initial migaration in step 3
Run in Package manager console:
Note before run: Update databse with Data folder context (OldDataBaseContext is inside of your Data folder that created by step 2)
Update-Database -Context OldDataBaseContext
Delete data folder that created in Step 2
Go to snapshot and initial migration classes and change the deleted context from Data folder to main context that is exist in your database project (just fix it for build)
Run:
Note before run: Add migration for main context that have new database changes
Add-Migration newUpdate
Run:
Update-Database
I Hope this help someone.
If you are strongly believe, that new (EF7) database schema will match your old database schema (including index and key names) - you may run 'Initial' migration to empty (temporary) database and then copy __EFMigrationHistory table from there to your real database.
Otherwise, I recommend you create empty database using migration and use sql insert into ... select commands to copy data from your old database. Without this, you will receive exceptions when upgrading database later - for example changing index will lead to DropIndex and CreateIndex migration commands, and DropIndex will fail because there is no index with this name (index exist with other, pre-EF7 name).
In my projects - old (from EF6) and new database schemes are different, and I used second option.

Entity Framework always has pending migration

Using Entity Framework 6, with a SQL Server database and code first migrations, I have migrations set up and running "happily", however I'm finding that every time I go to add another migration I get the following error first off:
Unable to generate an explicit migration because the following explicit migrations are pending: [201602090629398_Initial, 201602090638322_FixSitePageColumns, 201602110313468_RemoveRequiredTemplateId]. Apply the pending explicit migrations before attempting to generate a new explicit migration."
If I run update-database -force it complains (naturally) that the script fails because of already having been applied. A strange combination of doign this again and then the add-migration works and I can carry on updating to the latest migration.
The list of "pending" migrations also grows with every addded migration over time.
What could cause this "pending" state, when the migration HAS already been applied? I can confirm that the database has already been updated, the migration exists in __MigrationHistory, and the program is running along happily.
EDIT
I've also just run get-migrations and the following is being returned:
PM> get-migrations
Retrieving migrations that have been applied to the target database.
201602110313468_RemoveRequiredTemplateId
201602110311536_RemoveRequiredTemplateId
201602090638322_FixSitePageColumns
201602090629398_Initial
The weird thing here (possibly a red herring) is that 201602110311536_RemoveRequiredTemplateId is not a migration in my project, I think it may have been one that I created and then deleted, I didn't ever implicitly apply it to the database but it's in the __MigrationHistory table.
This happened to me because when running Add-Migration it couldn't connect to the database to see what migrations had been applied. I don't have my password stored in the connection string. The fix was to run Add-Migration specifying a complete -ConnectionString and -SqlProvider
Add-Migration MigrationName -verbose -ConnectionString "data source=foo.database.windows.net;initial catalog=FOO_DB;user id=admin;password=`"REDACTED`";MultipleActiveResultSets=True;App=EntityFramework" -ConnectionProviderName "System.Data.SqlClient"
Remove the entry for removerequiredtemplateid from the migrations database table and rerun your migration procedure.
Optionally, delete the table altogether, delete all of your migrations, rerun enable-migrations, create a new initial migration and run update-database again (basically, create a fresh start).
Remember to make the required backups beforehand.

EF - Moving from AutomaticMigrations to Manual Migrations

End of long day of testing various scenarios where I don't have to recreate a production database...
We started off with EF, and didn't get wise enough during development to move from automatic migrations to named migrations. Now I'm trying to rewind the clock, and create an initial migration that aligns with the production database.
Is this possible to align a model has with an automatic migration has in the migration table?
Should I just create an empty migration to get started with named migrations? My only problem with this is how to create the DB when a new developer joins... I could simply restore the db, and then apply migrations, but that ruins a beautiful EF migration story!
Delete the production DB, create, and write a script to re-import the data (sounds hacky).
Another wrinkle - the DB was created with EF5, and we are now developing with EF6.
Thanks in advance for your help.
It should be possible:
Delete the __MigrationHistory table
Delete any migrations in your project
Disable automatic migrations in your migrations configuration class
Add-Migration InitialCreate
Update-Database -Script
Execute the portion of the script that creates the __MigrationHistory table and inserts a row into it
Repeat steps 1 & 6 for any other existing databases
I also strongly recommend reading Code First Migrations in Team Environments.
If you don't like step 7 of bricelam's answer. Then keep reading.
Because upgrading from automatic migrations to manual can also be automated. And you don't need to delete the migrationhistory table like bricelam says.
In this case I assume you have one development machine, and multiple other (development) machines where databases already exist.
On your development machine you move your database into a safe location (keeping it safe to test your automatic upgrade procedure). (You might want to make sure your code is in the same exact state as all the database which you want to upgrade).
Delete any migrations in your project (you should't have any yet)
Disable automatic migrations in your migrations configuration class
Add-Migration InitialCreate
Put a backup (copy!) of your database back into place
On startup of your application (or your upgrade app) you do something like:
using (var db = new YourDatabaseContext())
{
InitialCreate.SkipInitialCreate = db.Database.Exists();
}
And in your InitialCreate you add something like:
public static bool SkipInitialCreate = false;
public override void Up()
{
// Skip initial create
if (SkipInitialCreate)
return;
This assumes that if a database exists it has the same structure as the one you had on your dev machine. Of course this could be way more complex than that for you. For more control you could inspect DbMigrator object for your config, and skip more than one migration. (would have been nice if you could query the hash of the model in the DbMigrator...)
After the code in step 4 add something like:
var configuration = new YourDatabaseConfiguration();
var migrator = new DbMigrator(configuration);
migrator.Update();
Start your application on your dev machine to test the upgrade. Your history table should have an automaticmigration record and a initialcreate record.
If everything works out you should be able to simple deploy and run the app on machines where the db already exists.
One very important aspect (and maybe the reason bricelam says you needed to delete the history table) is that if the AutomaticMigration record in that table is newer than one of your manual migrations you are going to have a Bad time. Because the migrator uses the dates to sort out the work it needs to do.
So if there are systems out there still automatically upgrading to the newest auto-upgrade model, then you are in a bit of a pickle.

Resetting EF Code-First Migration State

I'm using EF 5. We are looking to convert our project to use code-first migrations.
Originally in our DBContext file we had an IDataBaseInitializer implementation that creates the DB if it doesn't exist (using context.Database.Create).
I wanted to test out the migration concept so I originally ran the commands:
Enable-Migrations -ProjectName MyProjectName
(This successfully created a Migrations folder with a Configuration.cs file)
Add-Migration Initial -ProjectName MyProjectName
(This successfully created a script file which matched my model classes)
At this point I wanted to try testing upgrade scenario so I created a tmp field on my model and reran the Add-Migration command which seemed to work as expected.
However at this point I wanted to reset my state. I've reverted all my changes in VS, removed the files from the Migrations folder from disk, tried removing the __MigrationsHistory table from my DB (and also completely deleting the DB). No matter what I do I can't get a new Add-Migration to create a script that includes my initial state. It always appears as this... this is my test value that I created originally.
public partial class Initial : DbMigration
{
public override void Up()
{
DropColumn("dbo.EventTrackingRecords", "TestValue");
}
public override void Down()
{
AddColumn("dbo.EventTrackingRecords", "TestValue", c => c.String());
}
}
I don't understand where it's keeping this initial information. The only other thing that I found interesting is that if I run my program after deleting the DB, it recreates my DB as I would expect based on the model, but it also creates a __MigrationHistory table! I don't understand how the context.Database.Create() command is doing this.
EF creates the __MigrationHistory table to keep your DB up to date, and warn you if it's not.
When you edit something in your models, and run the add-migration, you have to run update-database to be able to create a new migration. EF won't allow you to have pending migrations while creating new ones.
So, if you add a property to one of your models, and then create a migration, you have to update the database before creating a new migration where you delete the property.
Hope this helps.