Восстановление базы данных Code-First без добавления каких-либо данных - PullRequest
4 голосов
/ 08 августа 2011

В моей первоначальной настройке кода я предпочитаю не позволять потребителю (в данном случае веб-странице) иметь возможность отбрасывать и воссоздавать базу данных даже во время разработки, опасаясь, что позже я могу забыть добавить соответствующую логику и снимать Я в ногу (для создания пользователей базы данных с соответствующими разрешениями, прежде чем начать работу). Поэтому этот сайт имеет три проекта, связанных с решением:

  • Код Первый проект , который содержит POCO и инициализаторы. Существует два различных способа создания экземпляра DbContext: один устанавливает Database.SetInitializer на инициализатор, который наследуется от CreateDatabaseIfNotExists<MyContext>, а другой - на DropCreateDatabaseAlways<PanelisternaDbContext>. Таким образом, я не получаю никаких скрытых выпадений и повторного создания, и, надеюсь, даже если позже я каким-то образом испорчу права доступа к базе данных, код на стороне сервера не помешает и начнёт удалять вещи.

  • Веб-страница проекта или вообще любой потребитель. Идея в том, что я создаю 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 ]

8 голосов
/ 11 августа 2011

В вашем консольном приложении вы можете поместить следующее:

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

Это должно вызвать сброс и воссоздать, и вы можете использовать пользовательский инициализатор для создания некоторых исходных данных, если требуется.

2 голосов
/ 08 августа 2011

Когда вы инициализируете DBContext, вы можете проверить, что база данных существует, и создать ее, если ее нет.

public MyDbContext(){
    Database.CreateIfNotExists();
}
1 голос
/ 22 апреля 2016

Существует четыре различных стратегии инициализации базы данных:

  1. CreateDatabaseIfNotExists: это инициализатор по умолчанию. Как следует из названия, он создаст базу данных, если ее нет в соответствии с конфигурацией. Однако если вы измените класс модели, а затем запустите приложение с этим инициализатором, оно выдаст исключение.
  2. DropCreateDatabaseIfModelChanges: этот инициализатор удаляет существующую базу данных и создает новую базу данных, если классы вашей модели (классы сущностей) были изменены. Таким образом, вам не нужно беспокоиться о поддержке схемы базы данных, когда ваши классы модели меняются.
  3. DropCreateDatabaseAlways: Как следует из названия, этот инициализатор удаляет существующую базу данных каждый раз, когда вы запускаете приложение, независимо от того, изменились классы вашей модели или нет. Это будет полезно, когда вам нужна свежая база данных, каждый раз, когда вы запускаете приложение, например, во время разработки приложения.
  4. Вы также можете создать свой собственный инициализатор, если какой-либо из вышеперечисленных не удовлетворяет вашим требованиям, или вы хотите выполнить какой-либо другой процесс, который инициализирует базу данных с использованием вышеуказанного инициализатора.
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

Вы также можете отключить инициализатор БД вашего приложения. Предположим, что для производственной среды вы не хотите терять существующие данные, тогда вы можете отключить инициализатор, как показано ниже:

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