Exploiter le CLI d’EF Core – partie 2 : génération du DbContext et du modèle de données à partir d’une base de données existante et génération des scripts SQL.

Entity Framwork Core dispose d’outils en ligne de commande (CLI) permettant d’automatiser certaines tâches qui, effectuées manuellement, prendraient beaucoup plus de temps au développeur. Dans la première partie de cette série de billets de blog sur l’utilisation du CLI d’EF Core, nous avons découvert les Migrations et comment utiliser cette fonctionnalité pour générer une base de données à partir du modèle de données et apportées des modifications à cette dernière.
Ce billet, comme de nombreux autres tutoriels sur la toile, aborde la génération de la base de données à partir du modèle objets, en utilisant l’approche Code First.
Toutefois, il peut arriver pour une nouvelle application que votre base de données existe déjà. Comment procéder ? S’arracher les cheveux pour créer manuellement le modèle de données correspondant à votre DbContext ? Non, vous n’avez pas besoin. Par ailleurs, sur de nombreux projets, la gestion de la base de données est déléguée à un DBA. Sur votre environnement de développement, vous pouvez disposer d’une base de données sur laquelle vous avez tous les droits et sur laquelle vous pouvez appliquer toute modification sans impact sur l’existant. Au moment de graduer votre application vers d’autres environnements, vous ne pouvez pas appliquer les Migrations comme vous le faites en environnement de développement. Vous devez donc générer les scripts SQL de mise à jour de votre base de données et les transmettre au DBA. Voyons comment procéder dans ce deuxième billet de blog de la série.
Génération des scripts SQL de mise à jour de la base de données
Nous allons reprendre l’application d’exemple du billet de blog précédent. Ouvrez l’invite de commande à partir du dossier racine de l’application, puis exécutez la commande suivante :
Dotnet ef migrations script
323463
Le code de Migrations disponible dans le dossier correspondant de notre application est traduit en un script SQL qui sera exécuté sur la base de données.
Nous avons donc un Create Table Todo pour la migration Initial et un Alter Table ToDO Add Done pour la migration UpdateTodo. Pour tracer les modifications effectuées à la base de données via les Migrations, un Insert Into _EFMigrationsHistory est effectué pour chaque Migration qui sera appliquée. Bien évidemment, on doit s’assurer que cette table existe et la créer dans le cas contraire. D’où le Create Table If Not Exists en début du script SQL.
Appliquer un Script SQL via la migration
Il peut arriver que le DBA applique des modifications à la BD dans les environnements dont il est responsable, et vous devez effectuer une mise à jour de votre base de données de développement en utilisant le script qui vous a été transmis. Pour le faire, vous devez simplement utiliser la méthode suivante :
migrationBuilder.Sql("ScriptSQL");
Cette méthode prend en paramètre le Script SQL qui sera exécuté. Elle doit être ajoutée dans la méthode Up du code de Migration qui n’a pas encore été appliquée à la base de données :
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.Sql("ScriptSQL");
migrationBuilder.AddColumn
name: "Done",
table: "ToDo",
type: "INTEGER",
nullable: false,
defaultValue: false);
}
Génération du modèle de données et le DBContext à partir d’une BD existante
Nous allons reprendre l’exemple du billet précédent. Vous allez supprimer le dossier Migrations, ainsi que tous les fichiers contenus dans le dossier Models. Vous devez garder la base de données todo.db, qui devrait ressembler à ceci :
323468
Pour générer le modèle de données et le DbContext correspondant pour cette base de données, nous allons utiliser la commande :
dotnet ef dbcontext scaffold
Ci-dessous les arguments et les différentes options qui peuvent être utilisés avec cette commande :
Arguments:
Options:
-d|--data-annotations Use attributes to configure the model (where possible). If omitted, only the fluent API is used.
-c|--context
-f|--force Overwrite existing files.
-o|--output-dir
--schema
-t|--table
--use-database-names Use table and column names directly from the database.
--json Show JSON output.
-p|--project
-s|--startup-project
--framework
--configuration
--runtime
--msbuildprojectextensionspath
--no-build Don't build the project. Only use this when the build is up-to-date.
-h|--help Show help information
-v|--verbose Show verbose output.
--no-color Don't colorize output.
--prefix-output Prefix output with level.
Pour notre cas, nous allons utiliser les arguments et options suivants :
Ce qui donne la commande suivante, qui doit être exécutée en invite de commande, dans le dossier Racine de l’application :
dotnet ef dbcontext scaffold "Data Source=todo.db" Microsoft.EntityFrameworkCore.SqLite -c MigrationsContext -o Models
Le fichier ToDo.cs, qui représente la table ToDo de notre base de données, ainsi que le fichier MigrationsContext.cs sont générés dans le dossier Models de l’application :
323478
Le code généré de la classe ToDo est le suivant :
public partial class ToDo
{
public long Id { get; set; }
public string CreatedDate { get; set; }
public string Description { get; set; }
public long Done { get; set; }
}
Et celui de la classe MigrationsContext est le suivant :
public partial class MigrationsContext : DbContext
{
public virtual DbSet
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
optionsBuilder.UseSqlite(@"Data Source=todo.db");
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity
{
entity.Property(e => e.Id).ValueGeneratedNever();
entity.Property(e => e.CreatedDate).IsRequired();
entity.Property(e => e.Description).IsRequired();
entity.Property(e => e.Done).HasDefaultValueSql("0");
});
}
}
C’est tout pour aujourd’hui. Dans le prochain billet de notre série, nous verrons comment utiliser les Migrations dans un pipeline d’intégration et livraison continue avec Visual Studio Team Services.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.