Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF Code First DropCreateDatabaseAlways not executed

I have a test application where I would like to drop and recreate database every time I run the application. This is my context class:

public class MySolutionContext : DbContext
{
    public MySolutionContext()
        : base("MySolution")
    {
        Database.SetInitializer<MySolutionContext>(new DropCreateDatabaseAlways());
    }

    public DbSet<Order> Orders { get; set; }
    public DbSet<OrderItem> OrderITems { get; set; }


    public void Seed(MySolutionContext context)
    {

        var order1 = new Order
        {
            Archive = false,
            CompletionDate = DateTime.Now,
            Person = "Bartosz"
        };
        var order2 = new Order
        {
            Archive = false,
            CompletionDate = DateTime.Now,
            Person = "Anna"
        };
        context.Orders.Add(order1);
        context.Orders.Add(order2);

        context.SaveChanges();
    }

    public class DropCreateDatabaseAlways : DropCreateDatabaseAlways<MySolutionContext>
    {
        protected override void Seed(MySolutionContext context)
        {
            context.Seed(context);
            base.Seed(context);
        }
    }
}

When I run the application for the first time, Seed method is executed and database gets created. However, when I stop and rerun the application, Seed method is not firing at all and previously created database is being used. Why does it happen? What am I missing in my code?

like image 581
Bartosz Avatar asked Aug 21 '14 09:08

Bartosz


2 Answers

The problem here is that migration is activated in your current project. Related to this article (http://entityframework.codeplex.com/workitem/1689), it's not possible to use migration AND "DropCreateDatabaseAlways" as the initializer at the same time.

If you want to use migration and "DropCreateDatabaseAlways" (which is completely useless, except from testing maybe), you'll have to write a own Init() method, which deletes and creates your database at every application start.

Database.Delete();
Database.Create();

But if you deactivate migration, you can use the initalizer "DropCreateDatabaseAlways".

If the problem is still there without migration here are some hints how to solve this kind of problem:

The Initializer is only executed if you are using the instance of the database or if the database doesn't exist. The seed method is part of your Initializer, so it doesn't get executed as well. To fix this problem you can "work" with the database by accessing part of the data like:

context.Set<Entity>.Count(); 

or any other method which works with the database.

Another solution is to force the database to call the Initializer:

Database.Initialize(true/false);

Hope this helps.

like image 107
0lli.rocks Avatar answered Nov 03 '22 06:11

0lli.rocks


In a test project, I also needed to drop the database and recreate everything each time I start the tests.

Simply adding the following line was not enough:

Database.SetInitializer(new DropCreateDatabaseAlways<MyContext>());

I tweaked it with this :

Database.SetInitializer(new DropCreateDatabaseAlways<ApsContext>());

using (MyContext context = new MyContext())
{
    context.Database.Delete();
}

It's important to know that, if migration is enabled, you need to actually call the database to create the schema. I simply call an entity trying to find something with Id = 0 (so it returns nothing).

like image 2
Maxime Avatar answered Nov 03 '22 07:11

Maxime