Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework 5 Migrations: Setting up an initial migration and single seed of the database

I have an MVC4 app which I've recently upgraded to Entity Framework 5 and I am trying to move our database over to using migrations from the development style of dropping and creating each run.

Here's what I've done in my app start function.

protected void Application_Start() {     Database.SetInitializer(         new MigrateDatabaseToLatestVersion< MyContext, Configuration >() );     ... } 

I ran the Enable-Migrations command on my repositories project and I thought that this would create an initial migration file however the only file it created was Configuration

When I delete the database it creates it as expected via code first and seeds the database from the Configuration file. In the configuration file I changed all the Add() functions to AddOrUpdate()

However it runs the seed function in my Configuration file each time the website starts and duplicates all the seed data again and again.

I imagined that it would create an initial migration file as the blog I read suggested that it would and I could put the seed data in there but it didn't

Can anyone explain how I should be setting up DB in code so that it only seeds once?


LINK: The migrations blog post I followed


While this is quite interesting for using the EF migrate.exe I've since switched to using roundhouse for running migrations. I still use EF to scaffold my migrations based on the models but I wrote a little console app to write the migrations out to SQL files. I then use roundhouse to perform the migrations themselves through my rake build scripts. There's a little more process involved but it's much more stable than using EF to perform the migrations on the fly when the application starts up.

like image 639
Neil Avatar asked Nov 22 '12 10:11

Neil


People also ask

What is entity migration in Entity Framework?

Entity Framework Migration. Migration. The Migrations feature enables you to change the data model and deploy your changes to production by updating the database schema without having to drop and re-create the database. It is the recommended way to evolve your application's database schema if you are using the Code First workflow.

How to use code first migrations in EF to seed the database?

Use Code First Migrations to Seed the Database. In this section, you will use Code First Migrations in EF to seed the database with test data. From the Tools menu, select NuGet Package Manager, then select Package Manager Console. In the Package Manager Console window, enter the following command:

What are migrations in EF Core?

The migrations feature in EF Core provides a way to incrementally update the database schema to keep it in sync with the application's data model while preserving existing data in the database.

How to create and update a database in Entity Framework?

Using migrations is a standard way to create and update a database with Entity Framework Core. The migration process has two steps: Creating migration and Applying migration. As we already said, our database schema must be aligned with the database model and every change in a database model needs to be migrated to the database itself.


1 Answers

This has proved to be a popular post so I have updated it in light of feedback from others. The main thing to know is that the Seed method in the Configuration class is run EVERY time the application starts, which isn't what the comment in the template method implies. See the answer from someone at Microsoft to this post about why that is - thanks to Jason Learmouth for finding that.

If you, like me, only want to run the database updates if there are any pending migrations then you need to do a bit more work. You can find that out if there are pending migrations by calling migrator.GetPendingMigrations(), but you have to do that in the ctor as the list of pending migrations is cleared before Seed method is called. The code to implement this, which goes in the Migrations.Configuration class is as follows:

internal sealed class Configuration : DbMigrationsConfiguration<YourDbContext> {      private readonly bool _pendingMigrations;      public Configuration()     {         // If you want automatic migrations the uncomment the line below.         //AutomaticMigrationsEnabled = true;         var migrator = new DbMigrator(this);         _pendingMigrations = migrator.GetPendingMigrations().Any();     }      protected override void Seed(MyDbContext context)     {         //Microsoft comment says "This method will be called after migrating to the latest version."         //However my testing shows that it is called every time the software starts          //Exit if there aren't any pending migrations         if (!_pendingMigrations) return;          //else run your code to seed the database, e.g.         context.Foos.AddOrUpdate( new Foo { bar = true});     } } 

I should point out that some people have suggested putting the seed code in the actual 'up' migration code. This works, but means you need to remember to put the seed code in each new migration and its pretty hard remember so I wouldn't do that. However if your seed changes with each migration then that might be the a good way to go.

like image 86
Jon P Smith Avatar answered Oct 04 '22 04:10

Jon P Smith