我有一个测试应用程序,我想在每次运行应用程序时删除并重新创建数据库。这是我的上下文类:
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方法根本没有触发,并且正在使用先前创建的数据库。为什么会这样?我的代码中缺少什么?
答案 0 :(得分:11)
此处的问题是您的当前项目中已激活迁移。与本文(http://entityframework.codeplex.com/workitem/1689)相关,无法同时使用迁移 AND “DropCreateDatabaseAlways”作为初始化程序。
如果你想使用迁移和“DropCreateDatabaseAlways”(除了测试之外完全没用),你必须编写一个自己的Init()方法,它在每次应用程序启动时删除并创建你的数据库。 / p>
Database.Delete();
Database.Create();
但是如果停用迁移,可以使用initalizer“DropCreateDatabaseAlways”。
如果问题仍然没有迁移,这里有一些提示如何解决这类问题:
只有在使用数据库实例或数据库不存在时才会执行初始化程序。种子方法是初始化程序的一部分,因此它也不会被执行。要解决此问题,您可以通过访问部分数据来“处理”数据库,如:
context.Set<Entity>.Count();
或与数据库一起使用的任何其他方法。
另一种解决方案是强制数据库调用初始化程序:
Database.Initialize(true/false);
希望这有帮助。
答案 1 :(得分:2)
在测试项目中,我还需要删除数据库并在每次开始测试时重新创建所有内容。
仅添加以下行是不够的:
Database.SetInitializer(new DropCreateDatabaseAlways<MyContext>());
我用这个调整了它:
Database.SetInitializer(new DropCreateDatabaseAlways<ApsContext>());
using (MyContext context = new MyContext())
{
context.Database.Delete();
}
重要的是要知道,如果启用了迁移,则需要实际调用数据库来创建模式。我只是调用一个实体试图找到Id = 0的东西(所以它什么都不返回)。