You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
mchsamples-.net-core/p08_BDD_EntityFramework
Marc CHEVALDONNE a773557095
continuous-integration/drone/push Build is failing Details
update to .NET6
2 years ago
..
ex_041_001_ConnectionStrings update to .NET6 2 years ago
ex_041_004_ConsoleTests_w_SQLite update to .NET6 2 years ago
ex_041_004_ConsoleTests_w_SqlServer update to .NET6 2 years ago
ex_041_004_TestingInMemory end of .NET5.0 update 2 years ago
ex_041_004_UnitTests_w_InMemory update to .NET6 2 years ago
ex_041_004_UnitTests_w_SQLiteInMemory update to .NET6 2 years ago
ex_042_001_EF_CF_conventions update to .NET6 2 years ago
ex_042_002_EF_CF_data_annotations update to .NET6 2 years ago
ex_042_003_EF_CF_Fluent_API update to .NET6 2 years ago
ex_042_004_Keys_conventions update to .NET6 2 years ago
ex_042_005_Keys_data_annotations update to .NET6 2 years ago
ex_042_006_Keys_FluentAPI update to .NET6 2 years ago
ex_042_007_ValueGeneration update to .NET6 2 years ago
ex_042_008_DataSeeding_before_EF2.1 update to .NET6 2 years ago
ex_042_009_DataSeeding update to .NET6 2 years ago
ex_042_010_SinglePropertyNavigation_conventions update to .NET6 2 years ago
ex_042_011_SinglePropertyNavigation_FluentAPI update to .NET6 2 years ago
ex_042_012_OneToOne_conventions update to .NET6 2 years ago
ex_042_013_OneToOne_FluentAPI update to .NET6 2 years ago
ex_042_014_OneToMany_dataAnnotations update to .NET6 2 years ago
ex_042_015_OneToMany_conventions update to .NET6 2 years ago
ex_042_016_OneToMany_FluentAPI update to .NET6 2 years ago
ReadMe.md Update ReadMe.md 4 years ago
Relationships.md Update Relationships.md 5 years ago
temp.md minor changes 5 years ago

ReadMe.md

Entity Framework Core 3.0

25/01/2020 ⋅ Marc Chevaldonné


Entity Framework (EF) Core est un ORM (Object-Relational Mapper) qui permet aux développeurs .NET de gérer de manière simple, légère et extensible, des bases de données. EF permet de gérer de nombreux providers (SQL Server, SQLite, Cosmos, ...) de manière transparente. EF vous permet également de mettre à jour vos bases de données et d'exécuter des requêtes sans avoir à écrire la moindre requête SQL. Vous pouvez passer par LINQ to SQL qui apportera plus de lisibilité et permettra au compilateur de vous aider à détecter vos erreurs.


Note:
Différentes solutions existent avec EF pour gérer une base de données dont le modèle existe par exemple. Dans ces exemples, je ne traiterai que la partie Code First, c'est-à-dire le cas où le modèle est créé à partir de vos classes.


Plan

Les exemples sont organisés selon le plan suivant:

  1. Fundamentals :
    Dans cette partie, je donnerai quelques notions pour se connecter à une base à l'aide de chaîne de connection (connection strings), comment utiliser des providers de tests.... Il s'agira en conséquence d'exemples simples manquants d'explications sur certains points, car ils seront présentés plus tard.
    • ex_041_001 : Connection Strings : montre comment utiliser une chaîne de connexion SQL Server ou SQLite.
    • ex_041_004 : Testing in memory : présente comment utiliser des fournisseurs en mémoire pour éviter la surchage de la création d'une base de données en particulier dans le cas de tests unitaires. Cet exemple est composé de 4 projets.
  2. Model :
    Ce chapitre s'attardera sur le lien entre le modèle et la base de données. En effet, avec EF, l'accès aux données se fait via le modèle, c'est-à-dire l'ensemble de vos classes (qui seront reliées à des tables créées plus ou moins automatiquement) ainsi qu'un contexte (DbContext) qui représentera une session de connexion avec votre (ou vos) base(s) de données. Je présenterai en conséquence tout d'abord comment écrire des classes pour votre modèle, puis comment écrire les différentes relations classiques (aggrégation, one to one, one to many, many to many, mais aussi les dictionnaires), comment gérer les héritages entre classes du modèle dans la base de données, etc.
  3. Schemas and migrations : Le but de ce chapitre sera de vous montrer comment garder votre modèle et votre base de données synchronisés.
  4. Querying (LINQ to SQL) and saving data : Language INtegrated Query (LINQ) est un outil de requête sur collections et sa version LINQ to SQL vous permet de passer très facilement à un système de requêtes sur les bases de données. Les requêtes LINQ sont automatiquement traduites en requêtes SQL, vous évitant ainsi d'avoir à écrire vos requêtes vous-mêmes. Elles sont dès lors beaucoup plus lisibles et faciles à écrire. Ce chapitre présente comment charger des données, réaliser du filtrage, de manière synchrone ou asynchrone, etc. Il montre bien sûr également comment réaliser le symétrique : mettre à jour, supprimer ou ajouter de nouvelles données dans la base.
  5. Database providers : EF vous permet de gérer votre base de données indépendamment du provider. Ce chapitre montrera donc comment utiliser différents providers parmi lesquels Microsoft SQL Server, SQLite ou encore InMemory dont le but est de permettre de tester la base en mémoire, sans passer par un provider.

Quelle version utiliser ?

Ces exemples sont écrits pour .NET Core 3.0, mais vous pouvez utiliser EF Core avec différents types projets. Voici les recommendations actuelles de Microsoft quant à l'utilisation des version d'EF.

EF Core 1.x 2.x 3.x
.NET Standard 1.3 2.0 2.1
.NET Core 1.0 2.0 3.0
.NET Framework 4.5.1 4.7.2 (not supported)
Mono 4.6 5.4 6.4
Xamarin.iOS 10.0 10.14 12.16
Xamarin.Android 7.0 8.0 10.0
UWP 10.0 10.0.16299 to be defined
Unity 2018.1 2018.1 to be defined

Comment lire ce tableau ?

Si vous voulez utiliser EF Core 3.0 avec une bibliothèque de classes écrites en .NET Standard, celle-ci doit utiliser au moins .NET Standard 2.1.

Si vous voulez utiliser EF Core 3.0 avec un projet Xamarin.iOS, celui-ci doit être au moins en version 12.16.

Si vous voulez utiliser EF Core dans une application UWP, vous ne pouvez pour le moment utiliser que EF Core 1.x ou 2.x.


Note :

Je n'ai pas l'intention de mettre à jour les exemples pour Entity Framework 6 ou pour .NET Framework, puisque la version 5 du framework va unifier .NET Framework et .NET Core. En conséquence, EF Core sera la nouvelle "norme".


Comment commencer ?

Un petit tutoriel rapide pour savoir comment créer un projet...

Prérequis

Il vous faut au moins la version 3.0 du SDK de .NET Core, mais celle-ci est certainement déjà installée si vous avez installé Visual Studio 2019 16.3 ou plus.

Créez un nouveau projet

Vous pouvez ensuite créer un nouveau projet .NET Core 3.x, pour cela :

  • lancez Visual Studio
  • créez un nouveau projet de type Console App (.NET Core) en C#
Installez EntityFramework Core

Pour ce tutoriel, nous pouvons utiliser SqlServer comme provider.

  • Pour cela, cliquez droit sur le projet, puis sélectionnez Gérer les packages NuGet....
  • Sous l'onglet Parcourir, dans la barre de recherche, rentrez Microsoft.EntityFrameworkCore
  • Sélectionnez le premier nuget dans sa version la plus récente et lancez l'installation.
  • Répétez les deux dernières opérations pour les packages :
    • Microsoft.EntityFrameworkCore.Design
    • Microsoft.EntityFrameworkCore.SqlServer
    • Microsoft.EntityFrameworkCore.SqlServer.Design
Créez un modèle
  • Ajoutez une nouvelle classe Nounours au projet.
  • Ajoutez le code suivant à cette classe :
using System;

namespace tutoRapideEFCore
{
    class Nounours
    {
        public int Id { get; set; }
        public string Nom { get; set; }
        public DateTime Naissance { get; set; }
        public int NbPoils { get; set; }
    }
}
  • Ajoutez une nouvelle classe NounoursContext qui servira de contexte à notre modèle.
  • Ajoutez le code suivante à cette classe :
using Microsoft.EntityFrameworkCore;

namespace tutoRapideEFCore
{
    class NounoursContext : DbContext
    {
        public DbSet<Nounours> Nounours { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder options)
            => options.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=myFirstDatabase.mdf;Trusted_Connection=True;");
    }
}

Créez la base de données
  • Ouvrez la Console du Gestionnaire de package, pour cela, dirigez-vous dans le menu Outils, puis Gestionnaire de package NuGet, puis Console du Gestionnaire de package.
  • Dans la console que vous venez d'ouvrir, déplacez-vous dans le dossier du projet (eg si votre projet s'apelle tutoRapideEFCore) :
cd tutoRapideEFCore
  • tapez ensuite les commandes suivantes :
dotnet ef migrations add myFirstMigration
dotnet ef database update 

Note:

Si vous n'avez pas installé correctement EntityFrameworkCore, il vous faudra peut-être utiliser également :

  • dotnet tool install --global dotnet-ef si vous utilisez la dernière version de .NET Core (3.1 aujourd'hui),

  • dotnet tool install --global dotnet-ef --version 3.0.0 si vous vous utiliser spécifiquement .NET Core 3.0.

Utilisez votre base de données via Entity Framework Core
  • Editez Program.cs et ajoutez le code suivant :
static void Main(string[] args)
{
    Nounours chewie = new Nounours { Nom = "Chewbacca", Naissance = new DateTime(1977, 5, 27), NbPoils = 1234567 };
    Nounours yoda = new Nounours { Nom = "Yoda", Naissance = new DateTime(1980, 5, 21), NbPoils = 3 };
    Nounours ewok = new Nounours { Nom = "Ewok", Naissance = new DateTime(1983, 5, 25), NbPoils = 3456789 };
    Nounours c3po = new Nounours { Nom = "C3PO", Naissance = new DateTime(1977, 5, 27), NbPoils = 0 };

    using (var context = new NounoursContext())
    {
        // Crée des nounours et les insère dans la base
        Console.WriteLine("Creates and inserts new Nounours");
        context.Add(chewie);
        context.Add(yoda);
        context.Add(ewok);
        context.Add(c3po);
        context.SaveChanges();
    }
}

Maintenant, lorsque vous lancerez l'application, la base de données contiendra 3 nounours. La base crée automatiquement des identifiants pour chaque Nounours.

  • Editez Program.cs pour rajouter les lignes suivantes à la fin de la méthode Main :
// Lit le premier nounours de la base dont le nom commence par 'e'
Console.WriteLine("Creates and executes a query retrieving the first Nounours of the database whose name starts with an \"e\":");
var eNounours = context.Nounours
    .Where(n => n.Nom.StartsWith("e"))
    .First();
Console.WriteLine($"{eNounours.Nom} (born in {eNounours.Naissance.Year})");

Cette requête LINQ vous permet de lire le premier nounours de la base de nounours triés par ordre alphabétique de noms.
Ceci nécessite de rajouter au-début du fichier Program.cs la ligne suivante :

using System.Linq;
  • Editez Program.cs pour rajouter les lignes suivantes à la fin de la méthode Main :
// Met à jour le nom du second nounours de la base
Console.WriteLine("Updates the name of the second nounours");
eNounours.Nom = "Wicket";
context.SaveChanges();

Cette partie du code montre comment mettre à jour un élément de la base de données.

  • Editez Program.cs pour rajouter les lignes suivantes à la fin de la méthode Main :
// récupère le nounours qui n'en est pas un et le supprime de la base
Console.WriteLine("Deletes one item from de database");
var droid = context.Nounours
    .SingleOrDefault(n => n.Nom.Equals("C3PO"));
context.Remove(droid);
context.SaveChanges();

Cette partie du code montre comment supprimer un élément de la base de données.

Voici un récapitulatif du fichier Program.cs :

using System;
using System.Linq;

namespace tutoRapideEFCore
{
    class Program
    {
        static void Main(string[] args)
        {
            Nounours chewie = new Nounours { Nom = "Chewbacca", Naissance = new DateTime(1977, 5, 27), NbPoils = 1234567 };
            Nounours yoda = new Nounours { Nom = "Yoda", Naissance = new DateTime(1980, 5, 21), NbPoils = 3 };
            Nounours ewok = new Nounours { Nom = "Ewok", Naissance = new DateTime(1983, 5, 25), NbPoils = 3456789 };
            Nounours c3po = new Nounours { Nom = "C3PO", Naissance = new DateTime(1977, 5, 27), NbPoils = 0 };

            using (var context = new NounoursContext())
            {
                // Crée des nounours et les insère dans la base
                Console.WriteLine("Creates and inserts new Nounours");
                context.Add(chewie);
                context.Add(yoda);
                context.Add(ewok);
                context.Add(c3po);
                context.SaveChanges();

                // Lit le premier nounours de la base dont le nom commence par 'e'
                Console.WriteLine("Creates and executes a query retrieving the first Nounours of the database whose name starts with an \"e\":");
                var eNounours = context.Nounours
                    .Where(n => n.Nom.StartsWith("e"))
                    .First();
                Console.WriteLine($"{eNounours.Nom} (born in {eNounours.Naissance.Year})");

                // Met à jour le nom du second nounours de la base
                Console.WriteLine("Updates the name of the second nounours");
                eNounours.Nom = "Wicket";
                context.SaveChanges();

                // récupère le nounours qui n'en est pas un et le supprime de la base
                Console.WriteLine("Deletes one item from de database");
                var droid = context.Nounours
                    .SingleOrDefault(n => n.Nom.Equals("C3PO"));
                context.Remove(droid);
                context.SaveChanges();
            }
        }
    }
}
  • Exécutez votre application pour vérifier son bon fonctionnement.
Vérifiez le contenu de la base de données avec l'Explorateur d'objets SQL Server

Vous pouvez vérifier le contenu de votre base en utilisant l'Explorateur d'objets SQL Server.

  • Pour cela, allez dans le menu Affichage puis Explorateur d'objets SQL Server.
  • Déployez dans l'Explorateur d'objets SQL Server :
    • SQL Server,
    • puis (localdb)\MSSQLLocalDB ...,
    • puis Bases de données
    • puis celle portant le nom de votre migration, dans mon cas : myFirstDatabase.Nounours.mdf
    • puis Tables
    • Faites un clic droit sur la table dbo.Nounours puis choisissez Afficher les données
    • Vous devriez maintenant pouvoir voir les données suivantes dans le tableau :
    Id Nom Naissance NbPoils
    1 Chewbacca 27/05/1977 00:00:00 1234567
    2 Yoda 21/05/1980 00:00:00 3
    3 Wicket 25/05/1983 00:00:00 3456789

Vous pouvez constater que l'Ewok a bien été renommé Wicket, et que C3PO a bien été supprimé.
Notez qu'il est également possible d'utiliser l'Explorateur d'objets SQL Server pour ajouter, modifier ou supprimer des données dans les tables.