Apprendre à exploiter le CLI d'EF Core - Partie 2 : génération du code à partir d'une BD existante
Par Hinault Romaric

Le , par Hinault Romaric, Responsable .NET
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 :

Code : Sélectionner tout
Dotnet ef migrations script

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 :

Code c# : Sélectionner tout
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 :

Code c# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
   protected override void Up(MigrationBuilder migrationBuilder) 
        { 
  
            migrationBuilder.Sql("ScriptSQL"); 
  
            migrationBuilder.AddColumn<bool>( 
                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 :


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 [arguments] [options]

Ci-dessous les arguments et les différentes options qui peuvent être utilisés avec cette commande :

Arguments:
<CONNECTION> The connection string to the database.
<PROVIDER> The provider to use. (E.g. Microsoft.EntityFrameworkCore.SqlServer)

Options:
-d|--data-annotations Use attributes to configure the model (where possible). If omitted, only the fluent API is used.
-c|--context <NAME> The name of the DbContext.
-f|--force Overwrite existing files.
-o|--output-dir <PATH> The directory to put files in. Paths are relative to the project directory.
--schema <SCHEMA_NAME>... The schemas of tables to generate entity types for.
-t|--table <TABLE_NAME>... The tables to generate entity types for.
--use-database-names Use table and column names directly from the database.
--json Show JSON output.
-p|--project <PROJECT> The project to use.
-s|--startup-project <PROJECT> The startup project to use.
--framework <FRAMEWORK> The target framework.
--configuration <CONFIGURATION> The configuration to use.
--runtime <RUNTIME_IDENTIFIER> The runtime to use.
--msbuildprojectextensionspath <PATH> The MSBuild project extensions path. Defaults to "obj".
--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 :

  • Chaîne de connexion : Data Source=todo.db
  • Provider : Microsoft.EntityFrameworkCore.SqLite
  • Dossier de destination : Models
  • Nom du DbContext : MigrationsContext


Ce qui donne la commande suivante, qui doit être exécutée en invite de commande, dans le dossier Racine de l’application :

Code : Sélectionner tout
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 :


Le code généré de la classe ToDo est le suivant :

Code c# : Sélectionner tout
1
2
3
4
5
6
7
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 :

Code c# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public partial class MigrationsContext : DbContext 
    { 
        public virtual DbSet<ToDo> ToDo { get; set; } 
  
        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<ToDo>(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.


Vous avez aimé cette actualité ? Alors partagez-la avec vos amis en cliquant sur les boutons ci-dessous :


 Poster un commentaire

Avatar de tresorunikin tresorunikin - Membre habitué https://www.developpez.com
le 01/11/2017 à 12:02
Merci pour ceci! C'est Cool et c'est comme nous en avions parlé en Janvier sur stackoverflow pour sql server avec la communauté: en attente de l'interface graphique au premier trimestre 2018. EF Core 2.1
Avatar de stailer stailer - Membre chevronné https://www.developpez.com
le 03/11/2017 à 8:58
Merci pour cet article très clair.

J'ai également consulté la doc Microsoft pour partir sur la création de la base en 1er :
https://docs.microsoft.com/en-us/ef/...re/existing-db

Malheureusement on est loin des automatismes fournis dans VS avec les précédentes version d'entity framework.

Tu aurais une idée de la date ou période ou on pourra créer un modèle d'entité aussi facilement ?
Avatar de Hinault Romaric Hinault Romaric - Responsable .NET https://www.developpez.com
le 16/11/2017 à 19:13
Citation Envoyé par stailer;bt6285
Merci pour cet article très clair.

J'ai également consulté la doc Microsoft pour partir sur la création de la base en 1er :
https://docs.microsoft.com/en-us/ef/...re/existing-db

Malheureusement on est loin des automatismes fournis dans VS avec les précédentes version d'entity framework.

Tu aurais une idée de la date ou période ou on pourra créer un modèle d'entité aussi facilement ?

L'approche adopté pour Entity Framework Core, tout comme ASP.NET Core et .NET Core en général c'est d’offrir des outils qui sont indépendants de tout environnement de développement. C'est pourquoi le recours à des commandes du CLI est privilégié. Maintenant c'est aux éditeurs d'EDI d'offrir des interfaces permettant de bénéficier d'une meilleure experience utilisateur.

Donc, à mon avis les développeurs d'Entity Framework Core ne vont pas mettre des efforts dans un support particulier de Visual Studio. Ce sera plus aux développeurs de Visual Studio de le faire.
Contacter le responsable de la rubrique Accueil