Les outils en ligne de commande de EF Core, ou EF Core .NET Command-line Tools, sont une extension de la commande (multi-plateforme) dotnet
. C’est d’ailleurs avec ces outils que l’on gère notre base de données lorsque l’on fait du Code First : dotnet ef database update
, dotnet ef migrations add XXXX
, … Donc, si vous avez installé le SDK, vous avez tout ce qu’il vous faut.
Avant de commencer, il est nécessaire de préciser qu’Entity Framework Core a été conçu pour une approche Code First. De ce fait, tout ce que nous allons voir dans cet article et les suivants, est susceptible d’être modifié voire supprimé. Cependant, il peut arriver que l’on ait besoin, pour une raison ou une autre (base de données d’une appli existante, …), de faire du Database First avec EF Core.
Dans cette série d’articles EF Core Database First, nous allons aborder différentes thématiques autour du Database First avec Entity Framework Core, dont voici la liste :
- Visite guidée
- Les outils en ligne de commande ( cet article)
- Personnaliser le code généré
- Quelques astuces utiles
Les commandes disponibles
Parmi ces outils, celui qui va nous intéresser s’appelle dbcontext
: comme son nom l’indique cela permet d’effectuer des opérations sur les contextes EF Core.
Si vous ouvrez une invite de commande (cmd
sous Windows) dans le dossier du projet de notre exemple ou d’un projet contenant un dbContext
et que vous exécutez la commande dotnet ef dbcontext --help
, vous devriez voir, entre autres choses, le résultat suivant :
Usage: dotnet ef dbcontext [options] [command]
Options:
-h|--help Show help information
-v|--verbose Show verbose output.
--no-color Don't colorize output.
--prefix-output Prefix output with level.
Commands:
info Gets information about a DbContext type.
list Lists available DbContext types.
scaffold Scaffolds a DbContext and entity types for a database.
Use "dbcontext [command] --help" for more information about a command.
Ce résultat est intéressant parce qu’il nous apprend:
- que l’on peut obtenir des informations à propos d’un
DbContext
existant : commandeinfo
. - que l’on peut lister les
DbContext
existants dans le dossier-projet courant : commandelist
. - que l’on peut créer un
DbContext
et les entités à partir d’une base de données : commandescaffold
.
Note : les lignes de commandes peuvent être exécutées avec powershell
comme avec la Package Manager Console
de Visual Studio.
La commande info
Il y a peu de choses à dire sur cette commande, si ce n’est qu’elle affiche les informations concernant le ou les DbContext
présents dans un projet.
En exécutant la commande dotnet ef dbcontext info
dans notre projet exemple, on peut obtenir le résultat suivant pour un DbContext
généré sans option :
Provider name: Microsoft.EntityFrameworkCore.SqlServer
Database name: EFCoreDBFirstMyStore
Data source: (localdb)\mssqllocaldb
Options: None
Dans le cas, ou l’on aurait plusieurs DbContext
dans le même projet, il possible de préciser le DbContext
en ajoutant l’option -c
ou --context
suivi par le nom du contexte.
Par exemple, si nous avions généré un DbContext
pour chacun des schémas de notre projet exemple, nous pourrions obtenir les informations sur le MyStoreStatsContext
(schéma stats
) en exécutant la commade suivante : dotnet ef dbcontext info -c MyStoreStatsContext
. Nous obtiendrions le résultat suivant :
Provider name: Microsoft.EntityFrameworkCore.SqlServer
Database name: EFCoreDBFirstMyStore
Data source: (localdb)\mssqllocaldb
Options: None
La commande list
Cette commande sert à lister les DbContext
présents dans le projet courant. Il suffit d’exécuter la commande suivante : dotnet ef dbcontext list
.
Pour reprendre l’exemple précédent avec un DbContext
par schéma, nous aurions le résultat suivant, avec notre projet exemple :
EFCoreDBFirst.MyStore.MyStoreContext
EFCoreDBFirst.MyStore.MyStoreStatsContext
La commande scaffold
Ce qui nous intéresse le plus pour du Database First, c’est la commande scaffold
mais nous verrons aussi les autres commandes à la fin de l’article.
Afin de voir les options que propose la commande scaffold
, nous allons commencer par exécuter la commande dotnet ef dbcontext scaffold --help
. Le résultat obtenu devrait ressembler à ceci :
Usage: dotnet ef dbcontext scaffold [arguments] [options]
Arguments:
The connection string to the database.
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 The name of the DbContext.
--context-dir The directory to put DbContext file in. Paths are relative to the project directory.
-f|--force Overwrite existing files.
-o|--output-dir The directory to put files in. Paths are relative to the project directory.
--schema ... The schemas of tables to generate entity types for.
-t|--table ... 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 The project to use.
-s|--startup-project The startup project to use.
--framework The target framework.
--configuration The configuration to use.
--runtime The runtime to use.
--msbuildprojectextensionspath 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.
Seules les options -d|--data-annotations
, -c|--context
, --context-dir
, -f|--force
, -o|--output-dir
, --schema
, -t|--table
et --use-database-names
vont nous intéresser.
Attention, il faut que le projet dans lequel vous exécutez la commande scaffold
compile. S’il ne compile pas, la commande ne s’exécutera pas. Nous verrons pourquoi dans le prochain article de la série.
Arguments obligatoires
A minima la commande scaffold
requiert de définir des arguments
qui sont :
- la connectionstring pour l’accès à la base de données.
- le provider à utiliser.
La connectionstring est tout simplement une connectionstring « classique ». Il est possible d’utiliser des connectionstring nommées mais nous verrons cela plus tard.
Le provider est le fournisseur permettant d’accéder à la base de données. Il en existe pour beaucoup de moteur de base de données : vous en trouverez une liste non exhaustive ici Database Providers.
Pour notre exemple, nous utiliserons :
–Server=(localdb)\mssqllocaldb;Database=EFCoreDBFirstMyStore;Trusted_Connection=True;
pour la connectionstring.
–Microsoft.EntityFrameworkCore.SqlServer
pour le provider.
Scaffolding sans option
Le scaffolding sans option permet de générer un DbContext
et les entités avec les options par défaut. Pour cela, il suffit d’exécuter la commande dotnet ef dbcontext scaffold "Server=(localdb)\mssqllocaldb;Database=EFCoreDBFirstMyStore;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer
pour obtenir le résultat suivant :
On peut constater que :
- tous les fichiers ont été générés à la racine de notre projet.
- le
DbContext
porte le nom de la base de données suffixé parContext
. - les entités portent le nom de la table correspondante.
- la connectionstring se retrouve en « dur » dans la méthode
OnConfiguring
duDbContext
. - la
FluentAPI
est utilisée, dans leDbContext
, pour définir les entités et leurs propriétés.
Option -d
ou --data-annotations
Si vous souhaitez que le code généré utilise les data-annotations plutôt que la FluentAPI, il suffit d’ajouter à la fin de la commande l’option -d
ou --data-annotations
.
Pour notre projet, la commande sera dotnet ef dbcontext scaffold "Server=(localdb)\mssqllocaldb;Database=EFCoreDBFirstMyStore;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -d
ou dotnet ef dbcontext scaffold "Server=(localdb)\mssqllocaldb;Database=EFCoreDBFirstMyStore;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer --data-annotations
.
On peut constater que des attributs ont été ajoutés sur les propriétés des entités. Cependant, comme l’aide de la commande le précise, les data-annotations sont utilisées quand c’est possible. C’est pour cette raison qu’il reste un peu de FluentAPI dans le DbContext
.
Option -c
ou --context
Si vous souhaitez personnaliser le nom de la classe du DbContext
, il suffit d’ajouter à la fin de la commande l’option -c
ou --context
suivi du nom désiré.
Pour notre projet, nous pourrions choisir comme nom MyStoreContext
au lieu de EFCoreDBFirstMyStore
. La commande sera dotnet ef dbcontext scaffold "Server=(localdb)\mssqllocaldb;Database=EFCoreDBFirstMyStore;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -c MyStoreContext
ou dotnet ef dbcontext scaffold "Server=(localdb)\mssqllocaldb;Database=EFCoreDBFirstMyStore;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer --context MyStoreContext
.
Voici le résultat obtenu :
Option --context-dir
Si vous souhaitez que votre DbContext
soit généré dans un dossier différent des entités, il suffit d’ajouter à la fin de la ligne de commande l’option --context-dir
suivi du nom du dossier en chemin relatif au dossier du projet.
Pour notre projet, nous pourrions choisir de générer le DbContext
dans un dossier nommé Context
. La commande serait dotnet ef dbcontext scaffold "Server=(localdb)\mssqllocaldb;Database=EFCoreDBFirstMyStore;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer --context-dir Context
Il est possible de définir un chemin de plusieurs dossiers : par exemple DAL\Context
. L’option deviendra --context-dir DAL\Context
pour donner ce résultat :

Option -f
ou --force
Si vous souhaitez mettre à jour un DbContext
existant et les entités, il suffit d’ajouter à la fin de la ligne de commande l’option -f
ou --force
.
Attention, dans le cas où une table aurait été supprimée de la base de données, cela ne supprimera pas le fichier de l’entité correspondante. Dans ce cas, il vaudra mieux supprimer les fichiers et relancer la commande de scaffolding sans cette option.
Pour notre projet, la commande sera dotnet ef dbcontext scaffold "Server=(localdb)\mssqllocaldb;Database=EFCoreDBFirstMyStore;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -f
ou dotnet ef dbcontext scaffold "Server=(localdb)\mssqllocaldb;Database=EFCoreDBFirstMyStore;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer --force
Option -o
ou output-dir
Si vous souhaitez générer votre DbContext
et les entités dans un dossier en particulier, il suffit d’ajouter à la fin de la ligne de commande l’option -o
ou --output-dir
suivi du nom du dossier en chemin relatif au dossier du projet.
Pour notre projet, nous pourrions choisir de générer le DbContext
et les entités dans un dossier nommée DAL
. La commande serait dotnet ef dbcontext scaffold "Server=(localdb)\mssqllocaldb;Database=EFCoreDBFirstMyStore;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -o DAL
ou dotnet ef dbcontext scaffold "Server=(localdb)\mssqllocaldb;Database=EFCoreDBFirstMyStore;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer --output-dir DAL
Il est possible de définir un chemin de plusieurs dossiers : par exemple Generated\DAL
. L’option deviendra --context-dir Generated\DAL
pour donner ce résultat :
Option --schema
Si vous avez plusieurs schémas dans votre base de données et que vous ne souhaitez pas tous les importer, il suffit d’ajouter à la fin de la ligne de commande l’option --schema
suivi du nom du schéma à importer. Il est possible d’importer plusieurs schémas en ajoutant autant d’options --schema
que l’on a de schémas à importer.
Pour notre projet, nous pourrions n’importer que le schéma dbo
. La commande serait dotnet ef dbcontext scaffold "Server=(localdb)\mssqllocaldb;Database=EFCoreDBFirstMyStore;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer --schema dbo
.
Ici, on peut voir que les tables Category
et Product
du schéma dbo
ont été importées et pas la table ProductView
du schéma stats
.
Option -t
ou --table
Si vous souhaitez importer certaines tables et pas d’autres, il suffit d’ajouter à la fin de la ligne de commande l’option -t
ou --table
suivi du nom de la table à importer : le nom de la table peut être préfixé par le nom du schéma (schema.table
). Il est possible d’importer plusieurs tables en ajoutant autant d’options que l’on a de tables à importer.
Attention, si vous importez des tables qui ont des clés étrangères vers des tables non importées, la commande retournera des warningvous avertissant qu’elle n’a pas pu modéliser la clé étrangère (et la navigation property).
Pour notre projet, nous pourrions choisir d’importer la table Product
du schéma dbo
et la table ProductView
du schéma stats
. La commande serait dotnet ef dbcontext scaffold "Server=(localdb)\mssqllocaldb;Database=EFCoreDBFirstMyStore;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -t Product -t stats.ProductView
Option --use-database-names
Si vous souhaitez que le nom des entités et des propriétés soient identiques à ce qui se trouve en base de données, il suffit d’ajouter à la fin de la ligne de commande l’option --use-database-names
.
Par défaut, EF Core « normalise » les noms de tables et les colonnes pour correspondre aux standards de C#
: à savoir du camel case. Par exemple, pour une table nommée product_view
, une entité nommée ProductView
. L’utilisation de l’option --use-database-names
permettra de garder le nom product_view
.