IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

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

0PARTAGES

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.

Une erreur dans cette actualité ? Signalez-nous-la !