Entity Framework - migracja Code First
Entity Framework 4.3 zawiera nową funkcję Migracje Code First, która umożliwia stopniowe rozwijanie schematu bazy danych w miarę zmian modelu w czasie. Dla większości programistów jest to duże ulepszenie w stosunku do opcji inicjowania bazy danych z wydań 4.1 i 4.2, które wymagały ręcznej aktualizacji bazy danych lub usunięcia i ponownego utworzenia po zmianie modelu.
Przed Entity Framework 4.3, jeśli masz już dane (inne niż dane wyjściowe) lub istniejące procedury składowane, wyzwalacze itp. W bazie danych, te strategie służyły do usuwania całej bazy danych i jej ponownego tworzenia, aby utracić dane i inną bazę danych obiekty.
Wraz z migracją automatycznie aktualizuje schemat bazy danych, gdy model ulegnie zmianie bez utraty istniejących danych lub innych obiektów bazy danych.
Używa nowego inicjatora bazy danych o nazwie MigrateDatabaseToLatestVersion.
Istnieją dwa rodzaje migracji -
- Migracja automatyczna
- Migracja oparta na kodzie
Migracja automatyczna
Migracja automatyczna została po raz pierwszy wprowadzona w Entity Framework 4.3. W przypadku migracji automatycznej nie ma potrzeby ręcznego przetwarzania migracji bazy danych w pliku kodu. Na przykład przy każdej zmianie trzeba będzie również zmienić klasy domeny. Ale w przypadku automatycznej migracji wystarczy uruchomić polecenie w konsoli Menedżera pakietów, aby to zrobić.
Przyjrzyjmy się poniższemu krok po kroku procesowi automatycznej migracji.
Korzystając z podejścia Code First, nie masz bazy danych dla swojej aplikacji.
W tym przykładzie zaczniemy od naszych 3 podstawowych klas, takich jak Student, Kurs i Rejestracja, jak pokazano w poniższym kodzie.
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; }
}
Poniżej znajduje się klasa kontekstu.
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; }
}
Przed uruchomieniem aplikacji należy włączyć automatyczną migrację.
Step 1 - Otwórz konsolę menedżera pakietów z menu Narzędzia → Menedżer pakietów NuGet → Konsola menedżera pakietów.
Step 2 - Aby włączyć automatyczną migrację, uruchom następujące polecenie w konsoli Menedżera pakietów.
PM> enable-migrations -EnableAutomaticMigrations:$true
Step 3 - Po pomyślnym uruchomieniu polecenie tworzy wewnętrzną zapieczętowaną klasę konfiguracji w folderze migracji projektu, jak pokazano w poniższym kodzie.
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" }
// );
}
}
}
Step 4 - Ustaw inicjator bazy danych w klasie kontekstu z nową strategią inicjowania bazy danych 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; }
}
Step 5- Skonfigurowałeś automatyczną migrację. Kiedy uruchomisz swoją aplikację, automatycznie zajmie się ona migracją, gdy zmienisz model.
Step 6- Jak widać, jedna tabela systemowa __MigrationHistory jest również tworzona w bazie danych z innymi tabelami. W __MigrationHistory automatyczna migracja zachowuje historię zmian w bazie danych.
Step 7- Gdy dodasz kolejną klasę encji jako klasę domeny i uruchomisz aplikację, utworzy ona tabelę w Twojej bazie danych. Dodajmy następującą klasę 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; }
}
Step 8 - Nie zapomnij dodać DBSet dla wyżej wymienionej klasy w swojej klasie kontekstu, jak pokazano w poniższym kodzie.
public virtual DbSet<StudentLogIn> StudentsLogIn { get; set; }
Step 9 - Uruchom ponownie aplikację, a zobaczysz, że tabela StudentsLogIn została dodana do Twojej bazy danych.
Powyższe kroki wymienione w przypadku migracji automatycznych będą działać tylko dla Twojej jednostki. Na przykład, aby dodać kolejną klasę jednostek lub usunąć istniejącą klasę jednostek, będzie ona pomyślnie migrowana. Ale jeśli dodasz lub usuniesz jakąkolwiek właściwość do swojej klasy encji, to zgłosi wyjątek.
Step 10 - Aby obsłużyć migrację właściwości, należy ustawić AutomaticMigrationDataLossAllowed = true w konstruktorze klasy konfiguracji.
public Configuration() {
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
ContextKey = "EFCodeFirstDemo.MyContext";
}
Migracja oparta na kodzie
Podczas opracowywania nowej aplikacji model danych często się zmienia, a za każdym razem, gdy model się zmienia, traci synchronizację z bazą danych. Skonfigurowano Entity Framework, aby automatycznie usuwać i ponownie tworzyć bazę danych za każdym razem, gdy zmienisz model danych. Migracja oparta na kodzie jest przydatna, gdy chcesz mieć większą kontrolę nad migracją.
Po dodaniu, usunięciu lub zmianie klas jednostek lub zmianie klasy DbContext przy następnym uruchomieniu aplikacji automatycznie usuwa istniejącą bazę danych, tworzy nową, która jest zgodna z modelem i wypełnia ją danymi testowymi.
Funkcja Migracje Code First rozwiązuje ten problem, umożliwiając Code First aktualizowanie schematu bazy danych zamiast porzucania i ponownego tworzenia bazy danych. Aby wdrożyć aplikację, musisz włączyć migracje.
Oto podstawowa zasada migracji zmian w bazie danych -
- Włącz migracje
- Dodaj migrację
- Zaktualizować bazę danych
Przyjrzyjmy się poniższemu krok po kroku procesowi migracji bazy kodu.
Kiedy używasz metody Code First, nie masz bazy danych dla swojej aplikacji.
W tym przykładzie zaczniemy ponownie od naszych 3 podstawowych klas, takich jak Student, Kurs i Rejestracja, jak pokazano w poniższym kodzie.
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; }
}
Poniżej znajduje się klasa kontekstu.
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; }
}
Step 1 - Przed uruchomieniem aplikacji należy włączyć migrację.
Step 2 - Otwórz konsolę Menedżera pakietów z Narzędzia → Menedżer pakietów NuGet → Konsola Menedżera pakietów.
Step 3 - Migracja jest już włączona, teraz dodaj migrację do aplikacji, wykonując następujące polecenie.
PM> add-migration "UniDB Schema"
Step 4 - Po pomyślnym wykonaniu polecenia zobaczysz, że w folderze Migration został utworzony nowy plik z nazwą parametru przekazanego do polecenia z prefiksem znacznika czasu, jak pokazano na poniższej ilustracji.
Step 5 - Bazę danych można utworzyć lub zaktualizować za pomocą polecenia „update-database”.
PM> Update-Database -Verbose
Flaga „-Verbose” wskazuje, że instrukcje SQL są stosowane do docelowej bazy danych w konsoli.
Step 6 - Dodajmy jeszcze jedną właściwość „Wiek” w klasie ucznia, a następnie wykonaj instrukcję aktualizacji.
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; }
}
Kiedy wykonasz PM → Update-Database –Verbose, kiedy polecenie zostanie pomyślnie wykonane, zobaczysz, że nowa kolumna Age jest dodana do twojej bazy danych.
Zalecamy wykonanie powyższego przykładu krok po kroku w celu lepszego zrozumienia.