How to run Seed() method of Configuration class of migrations
Asked Answered
K

9

47

I have 2 questions:

1) How can I run Seed() method from the package-manager console without updating-database model?

2) Is there a way how to call Seed() method in the code?

Thx for any advice.

Katharinekatharsis answered 28/5, 2013 at 8:5 Comment(2)
I ran into this issue with EF6 and then realized I had the wrong Default Project chosen, so the update-database did not find a configuration to run. It is good to note that just doing an update-database in EF6 will always run the Seed() method. I don't know if this was true at the time this was written.Dressingdown
I was having an issue where the seed method was not being called but I was running with the "- script" modifier. Remove this and the seed method gets called.Fahlband
K
26

After research I finally found the workaround for this issue:

1) Make Configuration public:

public sealed class Configuration : DbMigrationsConfiguration<YourContextClassHere>

2) Add the code below anywhere. It will run the latest migration and update your database:

Configuration configuration = new Configuration();
configuration.ContextType = typeof(YourContextClassHere);
var migrator = new DbMigrator(configuration);

//This will get the SQL script which will update the DB and write it to debug
var scriptor = new MigratorScriptingDecorator(migrator);
string script = scriptor.ScriptUpdate(sourceMigration: null, targetMigration: null).ToString();
Debug.Write(script);

//This will run the migration update script and will run Seed() method
migrator.Update();
Katharinekatharsis answered 27/6, 2013 at 9:19 Comment(1)
This answers the second part of the questions, but what about the first part How can I run Seed() method from the package-manager console without updating-database model?Adelina
A
50

Answering your first question. Create a Migration by running add-migration SeedOnly

Clear out all Up() and Down() code generated if there was any pending changes

public partial class SeedOnly : DbMigration
{
    public override void Up()
    {
    }

    public override void Down()
    {
    }
}

Then you can Target a Specific Migration by running update-database -TargetMigration SeedOnly in the Package Manager console

Ambi answered 30/12, 2015 at 6:46 Comment(1)
I suppose this is the best answer. It is amazing it has too few upvotes!Manual
K
26

After research I finally found the workaround for this issue:

1) Make Configuration public:

public sealed class Configuration : DbMigrationsConfiguration<YourContextClassHere>

2) Add the code below anywhere. It will run the latest migration and update your database:

Configuration configuration = new Configuration();
configuration.ContextType = typeof(YourContextClassHere);
var migrator = new DbMigrator(configuration);

//This will get the SQL script which will update the DB and write it to debug
var scriptor = new MigratorScriptingDecorator(migrator);
string script = scriptor.ScriptUpdate(sourceMigration: null, targetMigration: null).ToString();
Debug.Write(script);

//This will run the migration update script and will run Seed() method
migrator.Update();
Katharinekatharsis answered 27/6, 2013 at 9:19 Comment(1)
This answers the second part of the questions, but what about the first part How can I run Seed() method from the package-manager console without updating-database model?Adelina
H
7

Answering Question #2: Extract all the code from the Seed() method to another class. Then call that from within the Seed() method from the Configuration class:

    protected override void Seed(DbContext ctx)
    {
        new DatabaseSeed().Seed(ctx);
    }

Then you can call it from anywhere:

    new DatabaseSeed().Seed(new DbContext());
Heddie answered 25/6, 2014 at 15:56 Comment(1)
AddOrUpdate method is a method of DbContext so this doesn't work.Clothesline
J
3

Answer question 1:

People would usually work around this by either:

  1. Making a temporary artificial change to the model
  2. Switching to DropCreateDatabaseAlways, with the consequence that the database is often dropped and recreated when it is not needed
  3. Manually deleting the database

reference: http://blog.oneunicorn.com/2013/05/28/database-initializer-and-migrations-seed-methods/

Juback answered 31/12, 2015 at 6:57 Comment(0)
M
2

This is not exactly what you are looking for, but however take a look: Running Entity Framework Migrations via command line prompt This may help you or someone to forget application based database migration, because you can easily make scripts to run automatically...

Monger answered 30/9, 2016 at 5:24 Comment(1)
Yeap, it might be usefull for CI. Thanks.Katharinekatharsis
S
1

If you use context initiliazer as MigrateDatabaseToLatestVersion, seed method in configuration should be run automatically. Don't think you need to call it manually.

Sorn answered 29/5, 2013 at 15:21 Comment(2)
But what If I want to call it manualy? I made update-database in package manager console and get my Seed() method run. But I after it I do some job which deletes the information in DB. So I want to run the Seed() method indepenly of update-database. Any ideas?Katharinekatharsis
One option is to create sql script for using it in migration. this can be achieved by using update-database -script -targetmigration:<migration name>. Once the script is created, you can add any seed information you would like at the end of the script. These would be sql insert statements. You can run the script in the up method of the migration file created.Sorn
G
1

Add a new public method into the Configuration class. The new method only calls the protected method Seed:

public void RunSeed(DbContext db)
{
    Seed(db);
}

Then call the new method from eg. a unit test:

var db = new SomeDbContext();
var configuration = new Configuration();
configuration.RunSeed(db);
Graham answered 29/3, 2018 at 14:47 Comment(0)
A
1

I know this is a very old question, but in case someone hits here and for the purpose of sharing information:

To me, the simplest way to answer the question 1, would be solving question 2 first and then use the result to solve the first one. And that would be something as simple as @leifbattermann answered above (https://mcmap.net/q/361233/-how-to-run-seed-method-of-configuration-class-of-migrations) or @Martin Staufcik method too, and then just call the function/method in some piece of code that you can run whenever you want, with the amazing advantage that it can be used to set default values in some scenarios like creating new databases to new customers, among other.

Just don't forget, if you're using @leifbattermann method and calling the function from other place than the Configuration class and creating a new DbContext, you need to call SaveChanges() after. At least to me, that was the way.

Just one more thing: if you have no pending migrations and just wanna seed, just running the command "update-database" in Package Manager Console, will do the job.

Aegaeon answered 18/7, 2019 at 11:11 Comment(0)
F
0

If you want to Update-Database --Target-Migration xxx and you are surprised as i was that seed() method has not been run, you can try to git stash all your changes, generate database from previous version using Update-Database (to last revision which runs seed() always) and git stash apply then.

It is ugly workaround but it helped me.

Btw: don't forget to stage your changes before stashing

Furrow answered 10/3, 2017 at 16:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.