ASP.NET-MVC-4-and-Entity-Framework-Database-Migrations

Introduction :

Cet article est destiné à tous ceux qui utilisent / ou qui souhaitent  utiliser Entity Framework dans leurs couches d’accès aux données.

Suite à mon  retour d’expérience chez l’un de nos clients, je partage avec vous une des approches intéressantes qu’Entity Framework nous a apportées (Code First Migration) afin d'appliquer avec souplesse vos  modifications du modèle sur votre base de données, en réduisant les risques de pertes de données durant le cycle de vie de votre application.

 

Rappel :

Je commence par faire un petit rappel rapide aux gens qui ne connaissent pas le principe :

 

Mapping Objet Relationnel :

Le mapping objet relationnel est une technique permettant de convertir les données entre deux mondes à priori incompatibles, le monde objet, utilisé dans le code de l’application, et le monde relationnel servant à persister les données dans une base de données « relationnelle ».

Différentes approches :

Il y’a plusieurs manières d’aborder le problème selon qu’on se concentrera d’abord sur la base de données, le modèle, ou le code.

Database first:

Partir d’une base de donnée existante ou designer la base de donnée puis en déduire les objets et leurs mapping. C’est l’approche la plus rapide dans un environnement encore très marqué par les applications purement orientées données pour migrer des applications possédant déjà une base de données vers un Framework ORM.

Model first :

Modéliser les entités applicatives et leur mapping puis en déduire à la fois la base de données et les objets. Par cette approche on se concentre sur le noyau du mapping objet-relationnel et les 2 mondes « Objet » ou « Relationnel » sont vécus comme des projections de ce modèle.

Code first :

Coder les objets puis en déduire, par  conventions et/ou configuration, le mapping puis la base de données. Ici on code une application et les entités du modèle, le Framework se chargera de traduire vers une base de données cohérente.

Et c’est cette approche qui fera l’objet de la suite de notre article.

 

Entity Framework Code First Migrations :

 

Problématique :

Durant le cycle de vie de notre projet, nous nous sommes souvent trouvés confrontés à des situations (le plus souvent lors des livraisons sur les environnements de recette et de production) délicates de mise à jour de la base de données (Modification de la structure d’une table, ajout d’une nouvelle colonne etc…). Il a donc été décidé de « versionner » la base et Entity Framework, propose déjà ces mécanismes, avec en plus des fonctionnalités de migration automatique (que nous pouvons utiliser en développement) et/ou de génération de script.

 

Mise en place :

Tout d'abord Nuget doit être installé. Ensuite le package EntityFramework doit être installé avec Nuget (c’est déjà le cas sur notre projet).

Faire apparaitre la console Nuget : Tools => Library Package Manager => Package Manager Console.

Placer la console Nuget sur « Default Project » : (Par exemple xxx.DbContext) c’est le projet qui contient le DBContext et le mapping Entity Framework de la solution.

Dans la console, exécuter la commande suivante :

Enable-Migrations (Activation de la migration) :

Cette commande configure la migration dans le projet, ajoute un dossier « Migration » et une migration « Initiale ».

Exemple de la configuration initiale :

internalsealedclassConfiguration: DbMigrationsConfiguration<TestContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
}

La migration automatique est désactivée, sans cela, n’importe quelle modification du modèle serai impactée sur la base, sans même nécessiter les étapes volontaires qui sont expliquées au paragraphe suivant.

 

Pour permettre la mise à jour automatique de la base de données, on ajoute aussi un « initializer » au context, avec des instructions de pré-compilation pour faire en sorte que les migrations soient automatiquement appliquées sur nos environnements de développement et d’intégration continue.

static TestContext()
{
#if DEBUG
Database.SetInitializer(newMigrateDatabaseToLatestVersion<TestContext, Migrations.Configuration>());
#endif
}

 


Utilisation :

En développement :

En utilisant EF Migrations nous ne devons plus modifier la base directement ! Après chaque modification du modèle il faut lancer en premier la commande : Add-Migration < nom qu’on souhaite donner à la nouvelle migration > (sur le projet Data.DbContext).

Cette commande génère un nouveau fichier de migration, comportant la date et l’heure de création de cette migration (pour les passer dans l’ordre quand il y’en a plusieurs), il est possible de modifier/optimiser ensuite ces fichiers, mais nous allons nous en passer le plus souvent.

 

En production – En livraison :

Il est hors de question de laisser l’application mettre à jour automatiquement la base de données sur les environnements de production, c’est pourquoi dans ces cas, nous allons générer les scripts correspondant à la version à livrer.

Pour cela, dans la console Nuget, exécuter la commande :

Update-Database -SourceMigration <Version dans laquelle est déjà la base cible> -TargetMigration <Version cible> -Script

 Exemple :

Update-Database -Script -SourceMigration 201305130743581_InitialMigration -TargetMigration 201305141246344_Commande_AddColumn

 

Un fichier SQL est généré par cette commande :

ALTERTABLE [dbo].[Table] ADD [New_Column] [nvarchar](max)

INSERTINTO [__MigrationHistory]([MigrationId], [Model], [ProductVersion])VALUES ('201305141246344_Commande_AddColumn', 0x1F8B080000000000_________TRONQUE_________FFFAD77F0183EFC624F35C0800,'5.0.0.net40')

 

Ce fichier contient en fait 1 migration, qu’on peut identifier à sa fin : elle ajoute une ligne dans la table MigrationHistory, contenant le nom de la migration.

Pour à la fois permettre que les fichiers livrés puissent être joués plusieurs fois, et garantir qu’elle ne soient pas joués dans un ordre différent de celui qui a été prévu, il va nous falloir entourer l’exécution de chaque migration par un test :

if (Select top 1 MigrationId from [__MigrationHistory] order by MigrationId Desc) = 'Id_de_la_migration_précédente!’

begin

end

Et ainsi notre script de livraison de migration va pouvoir se ré-exécuter plusieurs fois, dans le bon ordre, sans que l’on doit déployer des trésors d’anticipation pour détecter les problèmes de N-Livraison.

 

Conclusion

J’espère que vous avez pu découvrir les avantages apportés par Entity Framework Code First Migration. Désormais, les modifications de votre modèle pourront être aisément appliquées à votre base de données avec le moins d'effort possible.

Catégories : Entity Framework

1 commentaire

DCube · 18 novembre 2014 à 9 h 27 min

[…] dans son article « Entity Framework Code First Migrations » que vous pouvez trouver ici :  http://blog.dcube.fr/blog/2014/10/23/entity-framework-code-first-migrations-2/ […]

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *