无需添加任何数据即可重新生成Code-First数据库

时间:2011-08-08 14:24:44

标签: c# entity-framework ef-code-first

在我的代码优先设置中,我不希望消费者(在这种情况下是一个网页)能够在设计时删除并重新创建数据库,因为我担心以后会忘记添加适当的逻辑并进行拍摄我自己在脚下(为了在上线前创建具有适当权限的数据库用户)。因此,该网站有三个与该解决方案相关的项目:

  • 代码优先项目,其中包含POCO和初始值设定项。创建DbContext实例有两种不同的方法,一种是将Database.SetInitializer设置为一个继承自CreateDatabaseIfNotExists<MyContext>的启动器,另一种设置为DropCreateDatabaseAlways<PanelisternaDbContext>。这种方式我没有得到任何偷偷摸摸的下降&amp;重新创建,希望即使我以后以某种方式搞砸数据库用户权限,服务器端代码也不会精神错乱并开始删除。

  • 网页项目,或者通常是任何类型的消费者。我的想法是在这里创建MyContext,不会丢弃数据库。

  • 重置项目,这是一个实际上会删除并重新创建所有内容的控制台应用。它甚至要求我输入一些验证,所以我不会意外地运行它。

所以,到目前为止一切都很棒。除了我不知道如何实际删除和重新创建数据库而不放入任何内容。即以下代码执行我想要的操作:

using (var myContext = MyDbContext.GetContext("connectionString", true)) 
//The trailing 'true' marks that the database is to be dropped and recreated.
{
    var user = new User {};
    myContext.Users.Add(user);
    myContext.SaveChanges();
    myContext.Users.Remove(user);
    myContext.SaveChanges();
}

正如您所看到的,我正在添加和删除User对象,以便SaveChanges()实际上可以执行某些操作。如果我只是执行SaveChanges(),则数据库不会删除/重新创建。

所以,不用多说,我正在寻找一种更简洁的方法来实现数据库重建,以及对这种基于重置的解决方案的任何评论或想法。

3 个答案:

答案 0 :(得分:8)

在您的控制台应用中,您可以输入以下内容:

Database.SetInitializer(new DropCreateDatabaseAlways<MyDbContext>());         
using (var myContext = MyDbContext.GetContext("connectionString")) 
{           
    context.Database.Initialize(force: true);      
} 

这应该强制删除并重新创建,如果需要,您可以使用自定义初始值设定项创建一些初始数据。

答案 1 :(得分:2)

初始化DBContext时,可以检查数据库是否存在,如果不存在则创建数据库。

public MyDbContext(){
    Database.CreateIfNotExists();
}

答案 2 :(得分:1)

有四种不同的数据库初始化策略:

  
      
  1. CreateDatabaseIfNotExists:这是默认初始值设定项。顾名思义,如果根据配置不存在,它将创建数据库。但是,如果更改模型类,然后使用此初始化程序运行应用程序,则会抛出异常。
  2.   
  3. DropCreateDatabaseIfModelChanges:如果您的模型类(实体类)已更改,则此初始化程序将删除现有数据库并创建新数据库。因此,当模型类发生更改时,您不必担心维护数据库模式。
  4.   
  5. DropCreateDatabaseAlways:顾名思义,无论您的模型类是否已更改,每次运行应用程序时,此初始化程序都会删除现有数据库。当您在每次运行应用程序时需要新数据库时,这将非常有用,就像您在开发应用程序时一样。
  6.   
  7. 您也可以创建自己的自定义初始化程序,如果上述任何一项不满足您的要求,或者您想要使用上述初始化程序执行其他初始化数据库的过程。
  8.   
public class SchoolDBContext: DbContext { 
public SchoolDBContext(): base("SchoolDBConnectionString") 
{
    Database.SetInitializer<SchoolDBContext>(new CreateDatabaseIfNotExists<SchoolDBContext>());

    //Database.SetInitializer<SchoolDBContext>(new DropCreateDatabaseIfModelChanges<SchoolDBContext>());
    //Database.SetInitializer<SchoolDBContext>(new DropCreateDatabaseAlways<SchoolDBContext>());
    //Database.SetInitializer<SchoolDBContext>(new SchoolDBInitializer());
}
public DbSet<Student> Students { get; set; }
public DbSet<Standard> Standards { get; set; }
}

您还可以通过继承其中一个初始化程序

来创建自定义数据库初始值设定项
public class SchoolDBInitializer :  CreateDatabaseIfNotExists<SchoolDBContext>{ 
   protected override void Seed(SchoolDBContext context)
    {   
       base.Seed(context);  
    }
}

在Code-First中关闭DB Initializer

  

您还可以关闭应用程序的数据库初始化程序。假设,对于生产环境,您不希望丢失现有数据,那么您可以关闭初始化程序,如下所示:

public class SchoolDBContext : DbContext
{   
   public SchoolDBContext(): base("SchoolDBConnectionString")
   {
      //Disable initializer
      Database.SetInitializer<SchoolDBContext>(null);
   }
   public DbSet<Student> Students { get; set; }
   public DbSet<Standard> Standards { get; set; }
}