[Actualité] Exploiter le CLI d’EF Core – partie 2 : génération du code à partir d'une BD existante
par
, 30/10/2017 à 19h45 (2440 Affichages)
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 - Visualiser dans une fenêtre à part 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 - Visualiser dans une fenêtre à part 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 - Visualiser dans une fenêtre à part
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 :
Pour notre cas, nous allons utiliser les arguments et options suivants :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.
- 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 :
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 :
Code : Sélectionner tout - Visualiser dans une fenêtre à part dotnet ef dbcontext scaffold "Data Source=todo.db" Microsoft.EntityFrameworkCore.SqLite -c MigrationsContext -o Models
Le code généré de la classe ToDo est le suivant :
Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
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 - Visualiser dans une fenêtre à part
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.