Catégories
.Net

Entity Framework Code First 101

Les briques de base

Voici les étapes pour gérer une base de donnée avec Entity Framework en mode Code First avec la possibilité d’effectuer des migrations de Bases de Données simplement en modifiant du code C#.

Package NuGet

Les classes d’EntityFramework se trouvent dans le package NuGet du même nom, et elles sont dans les namespaces System.Data.Entity.* et System.ComponentModel.DataAnnotations.Schema

La base de données

La base de données est représentée par une dérivée de la classe DbContext, il faudra donc dériver de cette classe pour créer notre propre base de données.

  • créer une classe MonDBContext héritant de DbContext (dans System.Data.Entity)
  • appeler la base classe de MonDBContext avec en paramètre, le nom de la chaine de connexion
  • créer des propriétés DbSet<T> qui représentent les tables de notre BDD
  • créer les classes du domaine (domain classes) ou entités qui vont contenir la structure des tables (types des colonnes des tables) et qui sont simplement des classes POCO C#

Initializer

EF nous met à disposition 4 stratégies d’initialisation qui vont déterminer le comportement du code vis à vis du SGBD:

  • CreateDatabaseIfNotExists : va créer une nouvelle BDD uniquement s’il n’y en a pas déja une portant le même nom
  • DropCreateDatabaseIfModelChanges : va déruire la DBB existante et en recréer une si nos Entités ont été modifiées
  • DropCreateDatabaseAlways : détruit et recrée systématiquement la BDD
  • MigrateDatabaseToLatestVersion : va migrer automatiquement la BDD pour qu’elle correspondre au code
  • MonPropreDBInitializer  : dérivé de l’un des 4 types ci-dessus, il permet de populer la base avec des données initiales

nous devront en choisir une et la passer en paramètre à Database.SetInitializer.

Données de départ

Nous aurons souvent besoin de données une fois la base créée, que ce soit pour le début de vie de l’application, ou pour les tests.
Cela se fait dans notre propre Initializer (le 5ème type précédemment cité), hérité de d’une des 4 classes ci-dessus.

Il faut effectuer une surcharge de la méthode Seed héritée, terminer la méthode Seed par un base.Seed(context); (bien expliqué ici).

Exemple

Voilà à quoi devrait ressembler notre Context Entity Framework :

public class MonDBContext: DbContext
{
   public MonDBContext() : base("nomDeMaChaineDeConnexion")
  {       
    // Pour désactiver l'initialisation: Database.SetInitializer<MonDBContext>(null);
    Database.SetInitializer<MonDBContext>(new CreateDatabaseIfNotExists<MonDBContext>());
  }

  public DbSet<Entité1> Table1 { get; set; }
  public DbSet<Entité2> Table2 { get; set; }

  protected override void OnModelCreating(DbModelBuilder modelBuilder)
  {
    base.OnModelCreating(modelBuilder);
  }
}

Migrations

Une des fonctionnalités phare d’EF est la possibilité d’effectuer les migrations de structure de la base de données et/ou des données, avec du code uniquement (ie sans SQL). Cela est extrêmement utile en phase de conception notamment.
Nous avons a disposition 2 modes de migrations: mode auto et mode manuel (code-based), mais dans les 2 cas, un dossier Migrations avec une classe Configuration.cs va être créé, ainsi qu’une table __MigrationsHistory dans la base de donnée, qui va permettre (en historisant les migrations), la synchronisation entre le code C# et la structure de la BDD.

Migration Auto

Pour rendre son projet migrable il faut exécuter la commande suivante dans la console Package Manager de Visual Studio (menu View => Other Windows) en faisant attention  de bien sélectionner le projet contenant EF dans la liste déroulante « Default Project« : Enable-Migrations -EnableAutomaticMigrations
(exécuter get-help Enable-Migrations -full  pour obtenir l’aide complète sur cette commande).

Cela va créer automatiquement un dossier ~\Migrations dans votre projet avec un fichier Configuration contenant une classe Configuration : DbMigrationsConfiguration<MonDbContext>  .
Nous pouvons justement « configurer » la migration grâce au constructeur de cette classe (voir ci-dessous) :

internal sealed class Configuration : DbMigrationsConfiguration<MonDbContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = true;
        AutomaticMigrationDataLossAllowed = false;
    }

    protected override void Seed(MonDbContext context)
    {
        SeedUsersRoles(context);
    }
...
}

Dernier point, il est conseillé (surtout si vous avez déjà des données en base) d’utiliser l’initializer MigrateDatabaseToLatestVersion pour effectuer des migrations auto.

Migration Manuelle

Comme pour la migration Auto il faut effectuer un Enable-Migrations (sans l’option EnableAutomaticMigrations) pour préparer votre projet et votre BDD aux migrations, mais en mode manuel, il va falloir spécifier chaque étapes de migration (après avoir modifié vos Entités ou domain classes ) en exécutant (toujours dans la Console Package Manager) la commande :

  1. Add-Migration nomDeMaMigration  ce qui va générer un fichier timestampé dans le dossier Migrations et que vous pourrez modifier pour gérer par exemple les migrations ou modifications de données (get-help Add-Migration -Detailed  pour obtenir l’aide)
  2. Update-Database –verbose  qui va exécuter les migrations ajoutés et pas encore exécutés (pour l’aide get-help Update-Database -Detailed)

Retour arrière

Avec les migrations manuelles il est possible d’effectuer des rollbacks pour revenir en arrière (sous réserve de ne pas avoir détruit vos données), il suffit d’exécuter

update-database -TargetMigration:nomDunDeMesMigrationsPrecedente

Erreurs

Si vous démarrez non pas d’une feuille vierge mais avec une BDD existante, le 1re Add-Migration doit comporter le paramètre IgnoreChanges: Add-Migration InitialCreate -IgnoreChanges suivi d’un normal Update-Database

Bien faire attention :

  1. d’exécuter ses commandes dans la Package Manager Console et pas une des autres consoles
  2. de bien sélectionner le projet contenant notre code EF (1ère erreur de la screenshot)
  3. tenter de relancer un Enable-Migrations sur un projet déjà activé ne sert à rien (2ème erreur de la screenshot)
EF Migration Errors

Liens

Tutos MSDN: EF- & MVC5

Stratégies d’initialisation

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée.