Entity Framework 4.3 включает в себя новую функцию Code First Migrations, которая позволяет постепенно развивать схему базы данных по мере изменения модели с течением времени. Для большинства разработчиков это является большим улучшением по сравнению с опциями инициализатора базы данных из выпусков 4.1 и 4.2, которые требуют ручного обновления базы данных или ее удаления и повторного создания при изменении модели.
-
До Entity Framework 4.3, если у вас уже есть данные (кроме начальных данных) или существующие хранимые процедуры, триггеры и т. Д. В вашей базе данных, эти стратегии использовались для удаления всей базы данных и ее воссоздания, чтобы вы потеряли данные и другие БД. объекты.
-
При миграции он автоматически обновит схему базы данных, когда ваша модель изменится без потери каких-либо существующих данных или других объектов базы данных.
-
Он использует новый инициализатор базы данных с именем MigrateDatabaseToLatestVersion.
До Entity Framework 4.3, если у вас уже есть данные (кроме начальных данных) или существующие хранимые процедуры, триггеры и т. Д. В вашей базе данных, эти стратегии использовались для удаления всей базы данных и ее воссоздания, чтобы вы потеряли данные и другие БД. объекты.
При миграции он автоматически обновит схему базы данных, когда ваша модель изменится без потери каких-либо существующих данных или других объектов базы данных.
Он использует новый инициализатор базы данных с именем MigrateDatabaseToLatestVersion.
Есть два вида миграции —
- Автоматизированная миграция
- Миграция на основе кода
Автоматизированная миграция
Автоматизированная миграция была впервые представлена в Entity Framework 4.3. При автоматической миграции вам не нужно обрабатывать миграцию базы данных вручную в файле кода. Например, для каждого изменения вам также нужно будет изменить классы вашего домена. Но для автоматической миграции вам просто нужно выполнить команду в консоли диспетчера пакетов, чтобы сделать это.
Давайте посмотрим на следующий пошаговый процесс автоматической миграции.
Когда вы используете подход Code First, у вас нет базы данных для вашего приложения.
В этом примере мы начнем с наших 3 основных классов, таких как ученик, курс и зачисление, как показано в следующем коде.
public class Enrollment { public int EnrollmentID { get; set; } public int CourseID { get; set; } public int StudentID { get; set; } public Grade? Grade { get; set; } public virtual Course Course { get; set; } public virtual Student Student { get; set; } } public class Student { public int ID { get; set; } public string LastName { get; set; } public string FirstMidName { get; set; } public DateTime EnrollmentDate { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; } } public class Course { public int CourseID { get; set; } public string Title { get; set; } [Index] public int Credits { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; } }
Ниже приводится контекстный класс.
public class MyContext : DbContext { public MyContext() : base("MyContextDB") {} public virtual DbSet<Course> Courses { get; set; } public virtual DbSet<Enrollment> Enrollments { get; set; } public virtual DbSet<Student> Students { get; set; } }
Перед запуском приложения необходимо включить автоматическую миграцию.
Шаг 1 — Откройте Консоль менеджера пакетов из Сервиса → Менеджер пакетов NuGet → Консоль менеджера пакетов.
Шаг 2. Чтобы включить автоматическую миграцию, выполните следующую команду в консоли диспетчера пакетов.
PM> enable-migrations -EnableAutomaticMigrations:$true
Шаг 3. После успешного выполнения команды она создает внутренний запечатанный класс Configuration в папке Migration вашего проекта, как показано в следующем коде.
namespace EFCodeFirstDemo.Migrations { using System; using System.Data.Entity; using System.Data.Entity.Migrations; using System.Linq; internal sealed class Configuration : DbMigrationsConfiguration<EFCodeFirstDemo.MyContext> { public Configuration() { AutomaticMigrationsEnabled = true; ContextKey = "EFCodeFirstDemo.MyContext"; } protected override void Seed(EFCodeFirstDemo.MyContext context) { // This method will be called after migrating to the latest version. // You can use the DbSet<T>.AddOrUpdate() helper extension method // to avoid creating duplicate seed data. E.g. // context.People.AddOrUpdate( // p ⇒ p.FullName, // new Person { FullName = "Andrew Peters" }, // new Person { FullName = "Brice Lambson" }, // new Person { FullName = "Rowan Miller" } // ); } } }
Шаг 4 — Установите инициализатор базы данных в классе контекста с помощью новой стратегии инициализации БД MigrateDatabaseToLatestVersion.
public class MyContext : DbContext { public MyContext() : base("MyContextDB") { Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, EFCodeFirstDemo.Migrations.Configuration>("MyContextDB")); } public virtual DbSet<Course> Courses { get; set; } public virtual DbSet<Enrollment> Enrollments { get; set; } public virtual DbSet<Student> Students { get; set; } }
Шаг 5 — Вы настроили автоматическую миграцию. Когда вы выполняете свое приложение, оно автоматически позаботится о переносе, когда вы измените модель.
Шаг 6 — Как вы видите, одна системная таблица __MigrationHistory также создается в вашей базе данных с другими таблицами. В __MigrationHistory автоматическая миграция поддерживает историю изменений базы данных.
Шаг 7 — Когда вы добавите другой класс сущности в качестве класса вашего домена и запустите приложение, оно создаст таблицу в вашей базе данных. Давайте добавим следующий класс StudentLogIn.
public class StudentLogIn { [Key, ForeignKey("Student")] public int ID { get; set; } public string EmailID { get; set; } public string Password { get; set; } public virtual Student Student { get; set; } }
Шаг 8 — Не забудьте добавить DBSet для вышеупомянутого класса в свой контекстный класс, как показано в следующем коде.
public virtual DbSet<StudentLogIn> StudentsLogIn { get; set; }
Шаг 9 — Запустите ваше приложение еще раз, и вы увидите, что таблица StudentsLogIn добавлена в вашу базу данных.
Вышеупомянутые шаги, упомянутые для автоматической миграции, будут работать только для вашей организации. Например, чтобы добавить другой класс сущностей или удалить существующий класс сущностей, он будет успешно перенесен. Но если вы добавите или удалите какое-либо свойство для вашего класса сущности, оно выдаст исключение.
Шаг 10. Для обработки миграции свойства необходимо установить AutomaticMigrationDataLossAllowed = true в конструкторе класса конфигурации.
public Configuration() { AutomaticMigrationsEnabled = true; AutomaticMigrationDataLossAllowed = true; ContextKey = "EFCodeFirstDemo.MyContext"; }
Миграция на основе кода
Когда вы разрабатываете новое приложение, ваша модель данных часто меняется, и каждый раз, когда модель меняется, она не синхронизируется с базой данных. Вы настроили Entity Framework для автоматического удаления и повторного создания базы данных при каждом изменении модели данных. Миграция на основе кода полезна, когда вам нужен больший контроль над миграцией.
-
Когда вы добавляете, удаляете или изменяете классы сущностей или изменяете свой класс DbContext, при следующем запуске приложения оно автоматически удаляет существующую базу данных, создает новую, соответствующую модели, и заполняет ее тестовыми данными.
-
Функция Code First Migrations решает эту проблему, позволяя Code First обновлять схему базы данных вместо ее удаления и повторного создания. Чтобы развернуть приложение, вам нужно включить миграцию.
Когда вы добавляете, удаляете или изменяете классы сущностей или изменяете свой класс DbContext, при следующем запуске приложения оно автоматически удаляет существующую базу данных, создает новую, соответствующую модели, и заполняет ее тестовыми данными.
Функция Code First Migrations решает эту проблему, позволяя Code First обновлять схему базы данных вместо ее удаления и повторного создания. Чтобы развернуть приложение, вам нужно включить миграцию.
Вот основное правило для переноса изменений в базу данных —
- Включить миграцию
- Добавить миграцию
- Обновление базы данных
Давайте посмотрим на следующий пошаговый процесс миграции кода.
Когда вы используете первый подход кода, у вас нет базы данных для вашего приложения.
В этом примере мы снова начнем с наших 3 основных классов, таких как ученик, курс и зачисление, как показано в следующем коде.
public class Enrollment { public int EnrollmentID { get; set; } public int CourseID { get; set; } public int StudentID { get; set; } public Grade? Grade { get; set; } public virtual Course Course { get; set; } public virtual Student Student { get; set; } } public class Student { public int ID { get; set; } public string LastName { get; set; } public string FirstMidName { get; set; } public DateTime EnrollmentDate { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; } } public class Course { public int CourseID { get; set; } public string Title { get; set; } [Index] public int Credits { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; } }
Ниже приводится контекстный класс.
public class MyContext : DbContext { public MyContext() : base("MyContextDB") { Database.SetInitializer(new MigrateDatabaseToLatestVersion< MyContext, EFCodeFirstDemo.Migrations.Configuration>("MyContextDB")); } public virtual DbSet<Course> Courses { get; set; } public virtual DbSet<Enrollment> Enrollments { get; set; } public virtual DbSet<Student> Students { get; set; } }
Шаг 1. Перед запуском приложения необходимо включить миграцию.
Шаг 2 — Откройте Консоль диспетчера пакетов из меню Инструменты → Диспетчер пакетов NuGet → Консоль диспетчера пакетов.
Шаг 3 — Миграция уже включена, теперь добавьте миграцию в ваше приложение, выполнив следующую команду.
PM> add-migration "UniDB Schema"
Шаг 4. После успешного выполнения команды вы увидите, что в папке Migration был создан новый файл с именем параметра, переданного команде с префиксом временной метки, как показано на следующем рисунке.
Шаг 5 — Вы можете создать или обновить базу данных с помощью команды «update-database».
PM> Update-Database -Verbose
Флаг «-Verbose» указывает, что операторы SQL применяются к целевой базе данных в консоли.
Шаг 6 — Давайте добавим еще одно свойство ‘Возраст’ в класс ученика и затем выполним оператор обновления.
public class Student { public int ID { get; set; } public string LastName { get; set; } public string FirstMidName { get; set; } public int Age { get; set; } public DateTime EnrollmentDate { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; } }
Когда вы выполните PM → Update-Database — Verbose, когда команда будет успешно выполнена, вы увидите, что новый столбец Age добавлен в вашу базу данных.
Мы рекомендуем вам выполнить вышеприведенный пример пошагово для лучшего понимания.