EF Code First DropCreateDatabaseAlways not executed

本文关键字:not executed DropCreateDatabaseAlways First Code EF | 更新日期: 2023-09-27 18:19:06

我有一个测试应用程序,我想在每次运行应用程序时删除并重新创建数据库。这是我的context类:

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);
        }
    }
}

当我第一次运行应用程序时,Seed方法被执行,数据库被创建。但是,当我停止并重新运行应用程序时,Seed方法根本没有触发,并且正在使用先前创建的数据库。为什么会这样呢?我的代码中遗漏了什么?

EF Code First DropCreateDatabaseAlways not executed

这里的问题是迁移是在您当前的项目中激活的。与本文(http://entityframework.codeplex.com/workitem/1689)相关的是,不可能同时使用migration "DropCreateDatabaseAlways"作为初始化项。

如果你想使用迁移和"DropCreateDatabaseAlways"(这是完全无用的,除了从测试可能),你必须写一个自己的Init()方法,它删除和创建您的数据库在每个应用程序启动。

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

但是如果你停用迁移,你可以使用初始化器"DropCreateDatabaseAlways"

如果没有迁移,问题仍然存在,这里有一些提示如何解决这类问题:

Initializer只在使用数据库实例或数据库不存在时执行。seed方法是初始化器的一部分,所以它不会被执行。要解决这个问题,您可以通过访问部分数据来"处理"数据库,如:

context.Set<Entity>.Count(); 

或任何其他与数据库一起工作的方法。

另一个解决方案是强制数据库调用初始化器:
Database.Initialize(true/false);

在一个测试项目中,我还需要在每次开始测试时删除数据库并重新创建所有内容。

仅仅添加以下行是不够的:

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

我这样调整:

Database.SetInitializer(new DropCreateDatabaseAlways<ApsContext>());
using (MyContext context = new MyContext())
{
    context.Database.Delete();
}

重要的是要知道,如果启用了迁移,您需要实际调用数据库来创建模式。我只是简单地调用一个实体,试图找到Id = 0的东西(所以它不返回任何东西)。