Framework Entity Core – Accès et gestion des données en mode pas à pas

Le Framework Entity est l’ORM (Object Relational Mapping) proposé par Microsoft, permettant d’exposer une vue et gestion des données orientées objet de données contenues dans les tables d’une base de données relationnelle. Dans cet article, nous créerons une simple application permettant d’afficher, ajouter, modifier et supprimer des données contenues dans une table d’une base de données SQL Server, avec le Framework Entity Core 2.2. Pour ce faire, il existe deux modes de mise en œuvre de ce framework :

  • Mode DataBase First : les entités (classes) sont générées à partir de la base de données
  • Mode Code First : le schéma de la base de données est généré à partir du code des entités (classes)

Dans cet article, nous utiliserons le mode DataBase First. La base de données est une base SQL dont le schéma est le suivant :

Configuration du projet
Dans votre projet .NET Core, pour mettre en œuvre le Framework Entity Core, ajouter les packages NuGet suivants (version 2.2.0) :

  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.Tools
  • Microsoft.EntityFrameworkCore.SqlServer (provider)

Création des entités (classes)
Pour créer des entités à partir du schéma de la base de données, saisir l’instruction ci-dessous dans console de gestion des packages NuGet (en modifiant les valeurs des attributs de la chaîne de connexion) :

Scaffold-DbContext "Server=.\SQL; Database=Formation; User id=UserDemo; password=xxxxxx;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models

Les entités générées sont visibles dans l’explorateur de solution :

Une classe est générée pour chaque table, auxquelles s’ajoute une classe de contexte de données dont le nom est le nom de la base de données auquel est suffixé Context, autrement dit dans notre projet, FormationContext. Cette classe permettra d’obtenir des données de la base de données (sous forme d’objets) et d’effectuer des ajouts, mises à jour et suppressions.

Stockage de la chaîne de connexion
Créer un fichier de configuration au format JSON appelé appSettings.json à la racine de votre projet. Valoriser la propriété intitulée « Copier dans le répertoire de sortie » de ce fichier avec la valeur « Copier si plus récent ». Puis, implémenter la chaine de connexion suivante (en modifiant les valeurs des attributs de la chaine de connexion) :

{
  "ConnectionStrings": {
    "CS_Formation": "Server=.\\SQL; Database=Formation; User id=UserDemo; password=pass;"
  }
}

Modification de la classe de contexte de données
Pour prendre en compte la chaîne de connexion définie précédemment, apporter les modifications suivantes à la classe de contexte de données FormationContext :

public partial class FormationContext : DbContext
{
    // Ajout.
    public string ConnexionString { get; }

    // Ajout.
    public FormationContext(string connexionString)
        : this()
    {
        this.ConnexionString = connexionString;
    }

    // Modification.
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            optionsBuilder.UseSqlServer(this.ConnexionString);
        }
    }

    ...

Initialisation
Lors du lancement de l’application :

static void Main(string[] args)
{
    // Variables locales.
    IConfiguration configuration;
    ConfigurationBuilder builder;
    FormationContext oContexte;
    List<Theme> oListeThemes;
    List<Formation> oListeFormations;
    Theme theme;

    try
    {
        // Obtention de la chaîne de connexion et instanciation de la classe de contexte de données.
        builder = new ConfigurationBuilder();
        builder.AddJsonFile("appsettings.json"); // Microsoft.Extensions.Configuration.Json
        configuration = builder.Build();
        oContexte = new FormationContext(configuration.GetConnectionString("CS_Formation"));
    }
    catch (Exception aEx)
    {
        Console.WriteLine(aEx.Message);
    }
    finally
    {
        Console.ReadKey();
    }
}

Chargement des données dans le contexte de données
Voici quelques exemples permettant de charger des données dans le contexte de données :

  • Chargement de la liste des thèmes de formation (un thème correspond à un groupe de formations) :
    oListeThemes = oContexte.Theme.ToList();
  • Liste de tous les thèmes de formation contenant au moins une formation.
    oListeThemes = (from oTheme in oContexte.Theme
                    where oTheme.Formation.Count > 0
                    select oTheme).ToList();

Par défaut, les données sont chargées dans le contexte de données « à la demande ». Ainsi pour charger la liste des formations, deux solutions :

  • Chargement des formations de tous les thèmes (via la méthode Include) :
    oListeThemes = (from oTheme in oContexte.Theme.Include(o => o.Formation)
                    where oTheme.Formation.Count > 0
                    select oTheme).ToList();
  • Chargement des formations d’un thème en particulier (ex : le premier de la liste) :
    oContexte.Entry(oListeThemes[0])
             .Collection(o => o.Formation)
             .Load();

Ajout d’un thème de formation
Pour ajouter un nouveau thème, créer un thème, puis l’ajouter dans le contexte de données, et persister cet ajout dans la base de données :

theme = new Theme();
theme.Libelle = "Nouveau";
oContexte.Theme.Add(theme);
oContexte.SaveChanges();

Modification d’un thème de formation
Pour modifier un thème, modifier les propriétés d’un thème, puis persister ces modifications dans la base de données :

theme.Libelle = "Modifié";
oContexte.SaveChanges();

Suppression d’un thème de formation
Pour supprimer un thème, marquer ce thème comme supprimé dans le contexte de données, puis persister cette suppression dans la base de données :

oContexte.Theme.Remove(theme);
oContexte.SaveChanges();

About: James RAVAILLE

Travaillant avec la plateforme Microsoft .NET depuis 2002, j’alterne les missions de formation et d’ingénierie avec cette plateforme. J’écris ce blog pour transmettre mes connaissances à tout développeur, qu’il soit débutant ou expérimenté.