Entity Framework - Migration Code First

Entity Framework 4.3 inclut une nouvelle fonctionnalité de migrations Code First qui vous permet de faire évoluer progressivement le schéma de base de données à mesure que votre modèle change au fil du temps. Pour la plupart des développeurs, il s'agit d'une grande amélioration par rapport aux options d'initialisation de la base de données des versions 4.1 et 4.2 qui vous obligeaient à mettre à jour manuellement la base de données ou à la supprimer et à la recréer lorsque votre modèle a changé.

  • Avant Entity Framework 4.3, si vous avez déjà des données (autres que des données de départ) ou des procédures stockées, des déclencheurs, etc. existants dans votre base de données, ces stratégies permettaient de supprimer toute la base de données et de la recréer, de sorte que vous perdriez les données et autres bases de données. objets.

  • Avec la migration, il mettra automatiquement à jour le schéma de la base de données, lorsque votre modèle change sans perdre de données existantes ou d'autres objets de base de données.

  • Il utilise un nouvel initialiseur de base de données appelé MigrateDatabaseToLatestVersion.

Il existe deux types de migration -

  • Migration automatisée
  • Migration basée sur le code

Migration automatisée

La migration automatisée a été introduite pour la première fois dans Entity Framework 4.3. Dans la migration automatisée, vous n'avez pas besoin de traiter la migration de la base de données manuellement dans le fichier de code. Par exemple, pour chaque modification, vous devrez également modifier vos classes de domaine. Mais avec la migration automatisée, il vous suffit d'exécuter une commande dans la console du gestionnaire de package pour y parvenir.

Jetons un coup d'œil au processus étape par étape suivant de migration automatisée.

Lorsque vous utilisez l'approche Code First, vous n'avez pas de base de données pour votre application.

Dans cet exemple, nous commencerons par nos 3 classes de base telles que Etudiant, Cours et Inscription, comme indiqué dans le code suivant.

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

}

Voici la classe de contexte.

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

Avant d'exécuter l'application, vous devez activer la migration automatisée.

Step 1 - Ouvrez la console du gestionnaire de packages depuis Outils → Gestionnaire de packages NuGet → Console du gestionnaire de packages.

Step 2 - Pour activer la migration automatisée, exécutez la commande suivante dans la console du gestionnaire de package.

PM> enable-migrations -EnableAutomaticMigrations:$true

Step 3 - Une fois que la commande s'exécute avec succès, elle crée une classe de configuration interne scellée dans le dossier Migration de votre projet, comme indiqué dans le code suivant.

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 - Définissez l'initialiseur de base de données dans la classe de contexte avec la nouvelle stratégie d'initialisation de base de données 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- Vous avez mis en place une migration automatisée. Lorsque vous exécutez votre application, elle se charge automatiquement de la migration, lorsque vous changez de modèle.

Step 6- Comme vous pouvez le voir, une table système __MigrationHistory est également créée dans votre base de données avec d'autres tables. Dans __MigrationHistory, la migration automatisée conserve l'historique des modifications de la base de données.

Step 7- Lorsque vous ajoutez une autre classe d'entité en tant que classe de domaine et exécutez votre application, elle crée la table dans votre base de données. Ajoutons la classe StudentLogIn suivante.

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 - N'oubliez pas d'ajouter le DBSet pour la classe mentionnée ci-dessus dans votre classe de contexte comme indiqué dans le code suivant.

public virtual DbSet<StudentLogIn> StudentsLogIn { get; set; }

Step 9 - Exécutez à nouveau votre application et vous verrez que la table StudentsLogIn est ajoutée à votre base de données.

Les étapes ci-dessus mentionnées pour les migrations automatisées ne fonctionneront que pour votre entité. Par exemple, pour ajouter une autre classe d'entité ou supprimer la classe d'entité existante, la migration réussira. Mais si vous ajoutez ou supprimez une propriété à votre classe d'entité, elle lèvera une exception.

Step 10 - Pour gérer la migration des propriétés, vous devez définir AutomaticMigrationDataLossAllowed = true dans le constructeur de classe de configuration.

public Configuration() {
   AutomaticMigrationsEnabled = true;
   AutomaticMigrationDataLossAllowed = true;
   ContextKey = "EFCodeFirstDemo.MyContext";
}

Migration basée sur le code

Lorsque vous développez une nouvelle application, votre modèle de données change fréquemment et à chaque fois que le modèle change, il se désynchronise avec la base de données. Vous avez configuré Entity Framework pour supprimer et recréer automatiquement la base de données chaque fois que vous modifiez le modèle de données. La migration basée sur le code est utile lorsque vous souhaitez plus de contrôle sur la migration.

  • Lorsque vous ajoutez, supprimez ou modifiez des classes d'entités ou que vous modifiez votre classe DbContext, la prochaine fois que vous exécutez l'application, elle supprime automatiquement votre base de données existante, en crée une nouvelle qui correspond au modèle et l'amorce avec des données de test.

  • La fonctionnalité Migrations Code First résout ce problème en permettant à Code First de mettre à jour le schéma de base de données au lieu de supprimer et de recréer la base de données. Pour déployer l'application, vous devrez activer les migrations.

Voici la règle de base pour migrer les modifications dans la base de données -

  • Activer les migrations
  • Ajouter une migration
  • Mettre à jour la base de données

Jetons un coup d'œil au processus étape par étape suivant de migration de base de code.

Lorsque vous utilisez d'abord le code, vous ne disposez pas d'une base de données pour votre application.

Dans cet exemple, nous recommencerons avec nos 3 classes de base telles que Étudiant, Cours et Inscription, comme indiqué dans le code suivant.

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

}

Voici la classe de contexte.

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 - Avant d'exécuter l'application, vous devez activer la migration.

Step 2 - Ouvrez la console du gestionnaire de packages depuis Outils → Gestionnaire de packages NuGet → Console du gestionnaire de packages.

Step 3 - La migration est déjà activée, ajoutez maintenant la migration dans votre application en exécutant la commande suivante.

PM> add-migration "UniDB Schema"

Step 4 - Lorsque la commande est exécutée avec succès, vous verrez qu'un nouveau fichier a été créé dans le dossier Migration avec le nom du paramètre que vous avez passé à la commande avec un préfixe d'horodatage comme indiqué dans l'image suivante.

Step 5 - Vous pouvez créer ou mettre à jour la base de données à l'aide de la commande «update-database».

PM> Update-Database -Verbose

L'indicateur "-Verbose" spécifie d'afficher les instructions SQL appliquées à la base de données cible dans la console.

Step 6 - Ajoutons une autre propriété 'Age' dans la classe étudiante, puis exécutons l'instruction de mise à jour.

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

}

Lorsque vous exécutez PM → Update-Database –Verbose, lorsque la commande est exécutée avec succès, vous verrez que la nouvelle colonne Age est ajoutée dans votre base de données.

Nous vous recommandons d'exécuter l'exemple ci-dessus étape par étape pour une meilleure compréhension.