Pages Razor avec Entity Framework Core dans ASP.NET Core - Tutoriel 1 sur 8Razor Pages with Entity Framework Core in ASP.NET Core - Tutorial 1 of 8

Par Tom Dykstra et Rick AndersonBy Tom Dykstra and Rick Anderson

Il s’agit du premier d’une série de tutoriels qui montrent comment utiliser Entity Framework (EF) Core dans une application ASP.NET Core Razor Pages.This is the first in a series of tutorials that show how to use Entity Framework (EF) Core in an ASP.NET Core Razor Pages app. Dans ces tutoriels, un site web est créé pour une université fictive nommée Contoso.The tutorials build a web site for a fictional Contoso University. Le site comprend des fonctionnalités comme l’admission des étudiants, la création de cours et les affectations des formateurs.The site includes functionality such as student admission, course creation, and instructor assignments. Le tutoriel utilise le code première approche.The tutorial uses the code first approach. Pour plus d’informations sur la suite de ce tutoriel en utilisant la première approche de base de données, voir ce problème Github.For information on following this tutorial using the database first approach, see this Github issue.

Télécharger ou afficher l’application terminée.Download or view the completed app. Télécharger les instructions.Download instructions.

PrérequisPrerequisites

Moteurs de base de donnéesDatabase engines

Les instructions Visual Studio utilisent la Base de données locale SQL Server, version de SQL Server Express qui s’exécute uniquement sur Windows.The Visual Studio instructions use SQL Server LocalDB, a version of SQL Server Express that runs only on Windows.

Les instructions Visual Studio Code utilisent SQLite, moteur de base de données multiplateforme.The Visual Studio Code instructions use SQLite, a cross-platform database engine.

Si vous choisissez d’utiliser SQLite, téléchargez et installez un outil tiers pour la gestion et l’affichage d’une base de données SQLite, comme Browser for SQLite.If you choose to use SQLite, download and install a third-party tool for managing and viewing a SQLite database, such as DB Browser for SQLite.

Résolution des problèmesTroubleshooting

Si vous rencontrez un problème que vous ne pouvez pas résoudre, comparez votre code au projet terminé.If you run into a problem you can't resolve, compare your code to the completed project. Un bon moyen d’obtenir de l’aide est de poster une question sur StackOverflow.com en utilisant le mot-clé ASP.NET Core ou le mot-clé EF Core.A good way to get help is by posting a question to StackOverflow.com, using the ASP.NET Core tag or the EF Core tag.

Exemple d’applicationThe sample app

L’application générée dans ces didacticiels est le site web de base d’une université.The app built in these tutorials is a basic university web site. Les utilisateurs peuvent afficher et mettre à jour les informations relatives aux étudiants, aux cours et aux formateurs.Users can view and update student, course, and instructor information. Voici quelques-uns des écrans créés dans le didacticiel.Here are a few of the screens created in the tutorial.

Page d’index des étudiants

Page de modification des étudiants

Le style de l’interface utilisateur de ce site repose sur les modèles de projet intégrés.The UI style of this site is based on the built-in project templates. Le tutoriel traite essentiellement de l’utilisation d’EF Core, et non de la façon de personnaliser l’interface utilisateur.The tutorial's focus is on how to use EF Core, not how to customize the UI.

Suivez le lien en haut de la page pour obtenir le code source du projet terminé.Follow the link at the top of the page to get the source code for the completed project. Le dossier cu30 contient le code de la version 3.0 d’ASP.NET Core.The cu30 folder has the code for the ASP.NET Core 3.0 version of the tutorial. Les fichiers qui reflètent l’état du code pour les tutoriels 1-7 se trouvent dans le dossier cu30snapshots.Files that reflect the state of the code for tutorials 1-7 can be found in the cu30snapshots folder.

Pour exécuter l’application après avoir téléchargé le projet terminé :To run the app after downloading the completed project:

  • Supprimez trois fichiers et un dossier dont le nom contient SQLite.Delete three files and one folder that have SQLite in the name.

  • Créez le projet.Build the project.

  • Dans la console du Gestionnaire de package (PMC), exécutez la commande suivante :In Package Manager Console (PMC) run the following command:

    Update-Database
    
  • Exécutez le projet pour amorcer la base de données.Run the project to seed the database.

Créer le projet d’application webCreate the web app project

  • Dans Visual Studio, dans le menu Fichier, sélectionnez Nouveau > Projet.From the Visual Studio File menu, select New > Project.
  • Sélectionnez Application web ASP.NET Core.Select ASP.NET Core Web Application.
  • Nommez le projet ContosoUniversity.Name the project ContosoUniversity. Il est important d’utiliser ce nom exact, en respectant l’utilisation des majuscules, de sorte que les espaces de noms correspondent au moment où le code est copié et collé.It's important to use this exact name including capitalization, so the namespaces match when code is copied and pasted.
  • Sélectionnez .NET Core et ASP.NET Core 3.0 dans les listes déroulantes, puis Application web.Select .NET Core and ASP.NET Core 3.0 in the dropdowns, and then select Web Application.

Configurer le style du siteSet up the site style

Configurez l’en-tête, le pied de page et le menu du site en mettant à jour Pages/Shared/_Layout.cshtml :Set up the site header, footer, and menu by updating Pages/Shared/_Layout.cshtml:

  • Remplacez chaque occurrence de « ContosoUniversity » par « Contoso University ».Change each occurrence of "ContosoUniversity" to "Contoso University". Il y a trois occurrences.There are three occurrences.

  • Supprimez les entrées de menu Home et Privacy et ajoutez les entrées About, Students, Courses, Instructors et Departments.Delete the Home and Privacy menu entries, and add entries for About, Students, Courses, Instructors, and Departments.

Les modifications sont mises en surbrillance.The changes are highlighted.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Contoso University</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-area="" asp-page="/Index">Contoso University</a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/About">About</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Students/Index">Students</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Courses/Index">Courses</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Instructors/Index">Instructors</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Departments/Index">Departments</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2019 - Contoso University - <a asp-area="" asp-page="/Privacy">Privacy</a>
        </div>
    </footer>

    <script src="~/lib/jquery/dist/jquery.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>

    @RenderSection("Scripts", required: false)
</body>
</html>

Dans Pages/Index.cshtml, remplacez le contenu du fichier par le code suivant de façon à remplacer le texte relatif à ASP.NET Core par le texte se rapportant à cette application :In Pages/Index.cshtml, replace the contents of the file with the following code to replace the text about ASP.NET Core with text about this app:

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<div class="row mb-auto">
    <div class="col-md-4">
        <div class="row no-gutters border mb-4">
            <div class="col p-4 mb-4 ">
                <p class="card-text">
                    Contoso University is a sample application that
                    demonstrates how to use Entity Framework Core in an
                    ASP.NET Core Razor Pages web app.
                </p>
            </div>
        </div>
    </div>
    <div class="col-md-4">
        <div class="row no-gutters border mb-4">
            <div class="col p-4 d-flex flex-column position-static">
                <p class="card-text mb-auto">
                    You can build the application by following the steps in a series of tutorials.
                </p>
                <p>
                    <a href="https://docs.microsoft.com/aspnet/core/data/ef-rp/intro" class="stretched-link">See the tutorial</a>
                </p>
            </div>
        </div>
    </div>
    <div class="col-md-4">
        <div class="row no-gutters border mb-4">
            <div class="col p-4 d-flex flex-column">
                <p class="card-text mb-auto">
                    You can download the completed project from GitHub.
                </p>
                <p>
                    <a href="https://github.com/dotnet/AspNetCore.Docs/tree/master/aspnetcore/data/ef-rp/intro/samples" class="stretched-link">See project source code</a>
                </p>
            </div>
        </div>
    </div>
</div>

Exécutez l’application pour vérifier que la page d’accueil (« Home ») s’affiche.Run the app to verify that the home page appears.

Modèle de donnéesThe data model

Les sections suivantes créent un modèle de données :The following sections create a data model:

Diagramme du modèle de données Course-Enrollment-Student

Un étudiant peut s’inscrire à un nombre quelconque de cours et un cours peut avoir un nombre quelconque d’élèves inscrits.A student can enroll in any number of courses, and a course can have any number of students enrolled in it.

L’entité StudentThe Student entity

Diagramme de l’entité Student

  • Créez un dossier Models dans le dossier de projet.Create a Models folder in the project folder.

  • Créez Models/Student.cs avec le code suivant :Create Models/Student.cs with the following code:

    using System;
    using System.Collections.Generic;
    
    namespace ContosoUniversity.Models
    {
        public class Student
        {
            public int ID { get; set; }
            public string LastName { get; set; }
            public string FirstMidName { get; set; }
            public DateTime EnrollmentDate { get; set; }
    
            public ICollection<Enrollment> Enrollments { get; set; }
        }
    }
    

La propriété ID devient la colonne de clé primaire de la table de base de données qui correspond à cette classe.The ID property becomes the primary key column of the database table that corresponds to this class. Par défaut, EF Core interprète une propriété nommée ID ou classnameID comme clé primaire.By default, EF Core interprets a property that's named ID or classnameID as the primary key. L’autre nom reconnu automatiquement de la clé primaire de classe Student est StudentID.So the alternative automatically recognized name for the Student class primary key is StudentID. Pour plus d’informations, voir EF Core - Keys.For more information, see EF Core - Keys.

La Enrollments propriété est une propriété de navigation.The Enrollments property is a navigation property. Les propriétés de navigation contiennent d’autres entités qui sont associées à cette entité.Navigation properties hold other entities that are related to this entity. Dans ce cas, la propriété Enrollments d’une entité Student contient toutes les entités Enrollment associées à cet étudiant.In this case, the Enrollments property of a Student entity holds all of the Enrollment entities that are related to that Student. Par exemple, si une ligne Student dans la base de données est associée à deux lignes Enrollment, la propriété de navigation Enrollments contient ces deux entités Enrollment.For example, if a Student row in the database has two related Enrollment rows, the Enrollments navigation property contains those two Enrollment entities.

Dans la base de données, une ligne Enrollment est associée à une ligne Student si sa colonne StudentID contient la valeur d’ID de l’étudiant.In the database, an Enrollment row is related to a Student row if its StudentID column contains the student's ID value. Par exemple, supposez qu’une ligne Student présente un ID égal à 1.For example, suppose a Student row has ID=1. Les lignes Enrollment associées auront un StudentID égal à 1.Related Enrollment rows will have StudentID = 1. StudentID est une clé étrangère dans la table Enrollment.StudentID is a foreign key in the Enrollment table.

La propriété Enrollments est définie en tant que ICollection<Enrollment>, car plusieurs entités Enrollment associées peuvent exister.The Enrollments property is defined as ICollection<Enrollment> because there may be multiple related Enrollment entities. Vous pouvez utiliser d’autres types de collection, comme List<Enrollment> ou HashSet<Enrollment>.You can use other collection types, such as List<Enrollment> or HashSet<Enrollment>. Quand vous utilisez ICollection<Enrollment>, EF Core crée une collection HashSet<Enrollment> par défaut.When ICollection<Enrollment> is used, EF Core creates a HashSet<Enrollment> collection by default.

L’entité EnrollmentThe Enrollment entity

Diagramme de l’entité Enrollment

Créez Models/Enrollment.cs avec le code suivant :Create Models/Enrollment.cs with the following code:

namespace ContosoUniversity.Models
{
    public enum Grade
    {
        A, B, C, D, F
    }

    public class Enrollment
    {
        public int EnrollmentID { get; set; }
        public int CourseID { get; set; }
        public int StudentID { get; set; }
        public Grade? Grade { get; set; }

        public Course Course { get; set; }
        public Student Student { get; set; }
    }
}

La propriété EnrollmentID est la clé primaire ; cette entité utilise le modèle classnameID à la place de ID par lui-même.The EnrollmentID property is the primary key; this entity uses the classnameID pattern instead of ID by itself. Pour un modèle de données de production, choisissez un modèle et utilisez-le systématiquement.For a production data model, choose one pattern and use it consistently. Ce tutoriel utilise les deux pour montrer qu’ils fonctionnent tous les deux.This tutorial uses both just to illustrate that both work. L’utilisation de ID sans classname facilite l’implémentation de certaines modifications du modèle de données.Using ID without classname makes it easier to implement some kinds of data model changes.

La propriété Grade est un enum.The Grade property is an enum. La présence du point d’interrogation après la déclaration de type Grade indique que la propriété Gradeaccepte les valeurs Null.The question mark after the Grade type declaration indicates that the Grade property is nullable. Une note (Grade) de valeur Null est différente d’une note zéro : la valeur Null signifie que la note n’est pas connue ou qu’elle n’a pas encore été attribuée.A grade that's null is different from a zero grade—null means a grade isn't known or hasn't been assigned yet.

La propriété StudentID est une clé étrangère, et la propriété de navigation correspondante est Student.The StudentID property is a foreign key, and the corresponding navigation property is Student. Une entité Enrollment est associée à une entité Student. Par conséquent, la propriété contient une seule entité Student.An Enrollment entity is associated with one Student entity, so the property contains a single Student entity.

La propriété CourseID est une clé étrangère, et la propriété de navigation correspondante est Course.The CourseID property is a foreign key, and the corresponding navigation property is Course. Une entité Enrollment est associée à une entité Course.An Enrollment entity is associated with one Course entity.

EF Core interprète une propriété en tant que clé étrangère si elle se nomme <navigation property name><primary key property name>.EF Core interprets a property as a foreign key if it's named <navigation property name><primary key property name>. Par exemple, StudentID est la clé étrangère pour la propriété de navigation Student, car la clé primaire de l’entité Student est ID.For example,StudentID is the foreign key for the Student navigation property, since the Student entity's primary key is ID. Les propriétés de clé étrangère peuvent également se nommer <primary key property name>.Foreign key properties can also be named <primary key property name>. Par exemple, CourseID puisque la clé primaire de l’entité Course est CourseID.For example, CourseID since the Course entity's primary key is CourseID.

L’entité CourseThe Course entity

Diagramme de l’entité Course

Créez Models/Course.cs avec le code suivant :Create Models/Course.cs with the following code:

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;

namespace ContosoUniversity.Models
{
    public class Course
    {
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int CourseID { get; set; }
        public string Title { get; set; }
        public int Credits { get; set; }

        public ICollection<Enrollment> Enrollments { get; set; }
    }
}

La propriété Enrollments est une propriété de navigation.The Enrollments property is a navigation property. Une entité Course peut être associée à un nombre quelconque d’entités Enrollment.A Course entity can be related to any number of Enrollment entities.

L’attribut DatabaseGenerated permet à l’application de spécifier la clé primaire, plutôt que de la faire générer par la base de données.The DatabaseGenerated attribute allows the app to specify the primary key rather than having the database generate it.

Générez le projet pour vérifier qu’il n’y a pas d’erreurs du compilateur.Build the project to validate that there are no compiler errors.

Générer automatiquement des modèles de pages StudentScaffold Student pages

Dans cette section, vous allez utiliser l’outil de génération de modèles automatique ASP.NET Core pour générer :In this section, you use the ASP.NET Core scaffolding tool to generate:

  • Une classe de contexte EF Core.An EF Core context class. Le contexte est la classe principale qui coordonne les fonctionnalités d’Entity Framework pour un modèle de données déterminé.The context is the main class that coordinates Entity Framework functionality for a given data model. Il dérive de la classe Microsoft.EntityFrameworkCore.DbContext.It derives from the Microsoft.EntityFrameworkCore.DbContext class.
  • Les pages Razor qui gèrent les opérations Create, Read, Update et Delete (CRUD) pour l’entité Student.Razor pages that handle Create, Read, Update, and Delete (CRUD) operations for the Student entity.
  • Créez un dossier Students dans le dossier Pages.Create a Students folder in the Pages folder.
  • Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le dossier Pages/Students, puis sélectionnez Ajouter > Nouvel élément généré automatiquement.In Solution Explorer, right-click the Pages/Students folder and select Add > New Scaffolded Item.
  • Dans le dialogue Ajouter l’échafaudage, sélectionnez les pages Razor à l’aide de l’entité Cadre (CRUD) > ADD.In the Add Scaffold dialog, select Razor Pages using Entity Framework (CRUD) > ADD.
  • Dans la boîte de dialogue Pages Razor avec Entity Framework (CRUD)  :In the Add Razor Pages using Entity Framework (CRUD) dialog:
    • Dans la liste déroulante Classe de modèle, sélectionnez Student (ContosoUniversity.Models).In the Model class drop-down, select Student (ContosoUniversity.Models).
    • Dans la ligne Classe du contexte de données, sélectionnez le signe + (plus).In the Data context class row, select the + (plus) sign.
    • Remplacez le nom du contexte de données ContosoUniversity.Models.ContosoUniversityContext par ContosoUniversity.Data.SchoolContext.Change the data context name from ContosoUniversity.Models.ContosoUniversityContext to ContosoUniversity.Data.SchoolContext.
    • Sélectionnez Ajouter.Select Add.

Les packages suivants sont automatiquement installés :The following packages are automatically installed:

  • Microsoft.VisualStudio.Web.CodeGeneration.Design
  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.Extensions.Logging.Debug
  • Microsoft.EntityFrameworkCore.Tools

Si vous rencontrez un problème à l’étape précédente, générez le projet et recommencez l’étape de génération de modèles automatique.If you have a problem with the preceding step, build the project and retry the scaffold step.

Le processus de génération de modèles automatique :The scaffolding process:

  • Crée les pages Razor suivantes dans le dossier Pages/Students :Creates Razor pages in the Pages/Students folder:
    • Create.cshtml et Create.cshtml.csCreate.cshtml and Create.cshtml.cs
    • Delete.cshtml et Delete.cshtml.csDelete.cshtml and Delete.cshtml.cs
    • Details.cshtml et Details.cshtml.csDetails.cshtml and Details.cshtml.cs
    • Edit.cshtml et Edit.cshtml.csEdit.cshtml and Edit.cshtml.cs
    • Index.cshtml et Index.cshtml.csIndex.cshtml and Index.cshtml.cs
  • Crée Data/SchoolContext. cs.Creates Data/SchoolContext.cs.
  • Ajoute le contexte à l’injection de dépendances dans Startup.cs.Adds the context to dependency injection in Startup.cs.
  • Ajoute une chaîne de connexion de base de données à appsettings.json.Adds a database connection string to appsettings.json.

Chaîne de connexion de base de donnéesDatabase connection string

La chaîne de connexion spécifie SQL Server LocalDB.The connection string specifies SQL Server LocalDB.

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "SchoolContext": "Server=(localdb)\\mssqllocaldb;Database=SchoolContext6;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

LocalDB est une version allégée du moteur de base de données SQL Server Express. Elle est destinée au développement d’applications, et non à une utilisation en production.LocalDB is a lightweight version of the SQL Server Express Database Engine and is intended for app development, not production use. Par défaut, la Base de données locale crée des fichiers .mdf dans le répertoire C:/Users/<user>.By default, LocalDB creates .mdf files in the C:/Users/<user> directory.

Mettre à jour la classe du contexte de base de donnéesUpdate the database context class

La classe principale qui coordonne les fonctionnalités d’EF Core pour un modèle de données déterminé est la classe du contexte de base de données.The main class that coordinates EF Core functionality for a given data model is the database context class. Le contexte est dérivé de Microsoft.EntityFrameworkCore.DbContext.The context is derived from Microsoft.EntityFrameworkCore.DbContext. Il spécifie les entités qui sont incluses dans le modèle de données.The context specifies which entities are included in the data model. Dans ce projet, la classe est nommée SchoolContext.In this project, the class is named SchoolContext.

Mettez à jour SchoolContext.cs avec le code suivant :Update SchoolContext.cs with the following code:

using Microsoft.EntityFrameworkCore;
using ContosoUniversity.Models;

namespace ContosoUniversity.Data
{
    public class SchoolContext : DbContext
    {
        public SchoolContext (DbContextOptions<SchoolContext> options)
            : base(options)
        {
        }

        public DbSet<Student> Students { get; set; }
        public DbSet<Enrollment> Enrollments { get; set; }
        public DbSet<Course> Courses { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Course>().ToTable("Course");
            modelBuilder.Entity<Enrollment>().ToTable("Enrollment");
            modelBuilder.Entity<Student>().ToTable("Student");
        }
    }
}

Le code en surbrillance crée une propriété DbSet<TEntity> pour chaque jeu d’entités.The highlighted code creates a DbSet<TEntity> property for each entity set. Dans la terminologie d’EF Core :In EF Core terminology:

  • Un jeu d’entités correspond généralement à une table de base de données.An entity set typically corresponds to a database table.
  • Une entité correspond à une ligne dans la table.An entity corresponds to a row in the table.

Comme un jeu d’entités contient plusieurs entités, les propriétés DBSet doivent être des noms au pluriel.Since an entity set contains multiple entities, the DBSet properties should be plural names. Comme l’outil de génération de modèles automatique a créé un DBSet Student, cette étape le remplace par le pluriel Students.Since the scaffolding tool created aStudent DBSet, this step changes it to plural Students.

Pour que le code Razor Pages corresponde au nouveau nom DBSet, apportez une modification globale à l’ensemble du projet en remplaçant _context.Student par _context.Students.To make the Razor Pages code match the new DBSet name, make a global change across the whole project of _context.Student to _context.Students. Il y a 8 occurrences.There are 8 occurrences.

Générez le projet pour vérifier qu’il n’y a pas d’erreurs du compilateur.Build the project to verify there are no compiler errors.

Startup.csStartup.cs

ASP.NET Core comprend l’injection de dépendances.ASP.NET Core is built with dependency injection. Certains services (comme le contexte de base de données EF Core) sont inscrits avec l’injection de dépendances au démarrage de l’application.Services (such as the EF Core database context) are registered with dependency injection during application startup. Ces services sont affectés aux composants qui les nécessitent (par exemple les Pages Razor) par le biais de paramètres de constructeur.Components that require these services (such as Razor Pages) are provided these services via constructor parameters. Le code de constructeur qui obtient une instance de contexte de base de données est indiqué plus loin dans le tutoriel.The constructor code that gets a database context instance is shown later in the tutorial.

L’outil de génération de modèles automatique a inscrit automatiquement la classe du contexte dans le conteneur d’injection de dépendances.The scaffolding tool automatically registered the context class with the dependency injection container.

  • Dans ConfigureServices, les lignes en surbrillance ont été ajoutées par l’outil de génération de modèles automatique :In ConfigureServices, the highlighted lines were added by the scaffolder:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
    
        services.AddDbContext<SchoolContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("SchoolContext")));
    }
    

Le nom de la chaîne de connexion est transmis au contexte en appelant une méthode sur un objet DbContextOptions.The name of the connection string is passed in to the context by calling a method on a DbContextOptions object. Pour le développement local, le système de configuration ASP.NET Core lit la chaîne de connexion à partir du fichier appsettings.json.For local development, the ASP.NET Core configuration system reads the connection string from the appsettings.json file.

Créer la base de donnéesCreate the database

Mettez à jour Program.cs pour créer la base de données si elle n’existe pas :Update Program.cs to create the database if it doesn't exist:

using ContosoUniversity.Data;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;

namespace ContosoUniversity
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var host = CreateHostBuilder(args).Build();

            CreateDbIfNotExists(host);

            host.Run();
        }

        private static void CreateDbIfNotExists(IHost host)
        {
            using (var scope = host.Services.CreateScope())
            {
                var services = scope.ServiceProvider;

                try
                {
                    var context = services.GetRequiredService<SchoolContext>();
                    context.Database.EnsureCreated();
                }
                catch (Exception ex)
                {
                    var logger = services.GetRequiredService<ILogger<Program>>();
                    logger.LogError(ex, "An error occurred creating the DB.");
                }
            }
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

La méthode EnsureCreated n’effectue aucune action s’il existe une base de données pour le contexte.The EnsureCreated method takes no action if a database for the context exists. S’il n’existe pas de base de données, elle crée la base de données et le schéma.If no database exists, it creates the database and schema. EnsureCreated active le workflow suivant pour gérer les modifications du modèle de données :EnsureCreated enables the following workflow for handling data model changes:

  • Supprimez la base de données.Delete the database. Toutes les données existantes sont perdues.Any existing data is lost.
  • Modifiez le modèle de données.Change the data model. Par exemple, ajoutez un champ EmailAddress.For example, add an EmailAddress field.
  • Exécutez l'application.Run the app.
  • EnsureCreated crée une base de données avec le nouveau schéma.EnsureCreated creates a database with the new schema.

Ce workflow fonctionne bien à un stade précoce du développement, quand le schéma évolue rapidement, aussi longtemps que vous n’avez pas besoin de conserver les données.This workflow works well early in development when the schema is rapidly evolving, as long as you don't need to preserve data. La situation est différente quand les données qui ont été entrées dans la base de données doivent être conservées.The situation is different when data that has been entered into the database needs to be preserved. Dans ce cas, procédez à des migrations.When that is the case, use migrations.

Plus tard dans cette série de tutoriels, vous supprimerez la base de données créée par EnsureCreated et procéderez à des migrations.Later in the tutorial series, you delete the database that was created by EnsureCreated and use migrations instead. Une base de données créée par EnsureCreated ne peut pas être mise à jour via des migrations.A database that is created by EnsureCreated can't be updated by using migrations.

Test de l'applicationTest the app

  • Exécutez l'application.Run the app.
  • Sélectionnez le lien Students, puis Créer nouveau.Select the Students link and then Create New.
  • Testez les liens Edit, Details et Delete.Test the Edit, Details, and Delete links.

Amorcer la base de donnéesSeed the database

La méthode EnsureCreated crée une base de données vide.The EnsureCreated method creates an empty database. Cette section ajoute du code qui remplit la base de données avec des données de test.This section adds code that populates the database with test data.

Créez Data/DbInitializer.cs avec le code suivant :Create Data/DbInitializer.cs with the following code:

using ContosoUniversity.Data;
using ContosoUniversity.Models;
using System;
using System.Linq;

namespace ContosoUniversity.Data
{
    public static class DbInitializer
    {
        public static void Initialize(SchoolContext context)
        {
            context.Database.EnsureCreated();

            // Look for any students.
            if (context.Students.Any())
            {
                return;   // DB has been seeded
            }

            var students = new Student[]
            {
                new Student{FirstMidName="Carson",LastName="Alexander",EnrollmentDate=DateTime.Parse("2019-09-01")},
                new Student{FirstMidName="Meredith",LastName="Alonso",EnrollmentDate=DateTime.Parse("2017-09-01")},
                new Student{FirstMidName="Arturo",LastName="Anand",EnrollmentDate=DateTime.Parse("2018-09-01")},
                new Student{FirstMidName="Gytis",LastName="Barzdukas",EnrollmentDate=DateTime.Parse("2017-09-01")},
                new Student{FirstMidName="Yan",LastName="Li",EnrollmentDate=DateTime.Parse("2017-09-01")},
                new Student{FirstMidName="Peggy",LastName="Justice",EnrollmentDate=DateTime.Parse("2016-09-01")},
                new Student{FirstMidName="Laura",LastName="Norman",EnrollmentDate=DateTime.Parse("2018-09-01")},
                new Student{FirstMidName="Nino",LastName="Olivetto",EnrollmentDate=DateTime.Parse("2019-09-01")}
            };

            context.Students.AddRange(students);
            context.SaveChanges();

            var courses = new Course[]
            {
                new Course{CourseID=1050,Title="Chemistry",Credits=3},
                new Course{CourseID=4022,Title="Microeconomics",Credits=3},
                new Course{CourseID=4041,Title="Macroeconomics",Credits=3},
                new Course{CourseID=1045,Title="Calculus",Credits=4},
                new Course{CourseID=3141,Title="Trigonometry",Credits=4},
                new Course{CourseID=2021,Title="Composition",Credits=3},
                new Course{CourseID=2042,Title="Literature",Credits=4}
            };

            context.Courses.AddRange(courses);
            context.SaveChanges();

            var enrollments = new Enrollment[]
            {
                new Enrollment{StudentID=1,CourseID=1050,Grade=Grade.A},
                new Enrollment{StudentID=1,CourseID=4022,Grade=Grade.C},
                new Enrollment{StudentID=1,CourseID=4041,Grade=Grade.B},
                new Enrollment{StudentID=2,CourseID=1045,Grade=Grade.B},
                new Enrollment{StudentID=2,CourseID=3141,Grade=Grade.F},
                new Enrollment{StudentID=2,CourseID=2021,Grade=Grade.F},
                new Enrollment{StudentID=3,CourseID=1050},
                new Enrollment{StudentID=4,CourseID=1050},
                new Enrollment{StudentID=4,CourseID=4022,Grade=Grade.F},
                new Enrollment{StudentID=5,CourseID=4041,Grade=Grade.C},
                new Enrollment{StudentID=6,CourseID=1045},
                new Enrollment{StudentID=7,CourseID=3141,Grade=Grade.A},
            };

            context.Enrollments.AddRange(enrollments);
            context.SaveChanges();
        }
    }
}

Le code vérifie si des étudiants figurent dans la base de données.The code checks if there are any students in the database. S’il n’y a pas d’étudiants, il ajoute des données de test à la base de données.If there are no students, it adds test data to the database. Il crée les données de test dans des tableaux et non dans des collections List<T> afin d’optimiser les performances.It creates the test data in arrays rather than List<T> collections to optimize performance.

  • Dans Program.cs, remplacez l’appel EnsureCreated par un appel DbInitializer.Initialize :In Program.cs, replace the EnsureCreated call with a DbInitializer.Initialize call:

    // context.Database.EnsureCreated();
    DbInitializer.Initialize(context);
    

Arrêtez l’application si elle est en cours d’exécution et exécutez la commande suivante dans la Console du gestionnaire de package :Stop the app if it's running, and run the following command in the Package Manager Console (PMC):

Drop-Database
  • Redémarrez l’application.Restart the app.

  • Sélectionnez la page Students pour examiner les données amorcées.Select the Students page to see the seeded data.

Afficher la base de donnéesView the database

  • Ouvrez l’Explorateur d’objets SQL Server (SSOX) à partir du menu Affichage de Visual Studio.Open SQL Server Object Explorer (SSOX) from the View menu in Visual Studio.
  • Dans SSOX, sélectionnez (localdb)\MSSQLLocalDB > Databases > SchoolContext-{GUID}.In SSOX, select (localdb)\MSSQLLocalDB > Databases > SchoolContext-{GUID}. Le nom de la base de données est généré à partir du nom de contexte indiqué précédemment, ainsi que d’un tiret et d’un GUID.The database name is generated from the context name you provided earlier plus a dash and a GUID.
  • Développez le nœud Tables.Expand the Tables node.
  • Cliquez avec le bouton droit sur la table Student et cliquez sur Afficher les données pour voir les colonnes créées et les lignes insérées dans la table.Right-click the Student table and click View Data to see the columns created and the rows inserted into the table.
  • Cliquez avec le bouton droit sur la table Student et cliquez sur Afficher le code pour voir comment le modèle Student est mappé au schéma de la table Student.Right-click the Student table and click View Code to see how the Student model maps to the Student table schema.

Code asynchroneAsynchronous code

La programmation asynchrone est le mode par défaut pour ASP.NET Core et EF Core.Asynchronous programming is the default mode for ASP.NET Core and EF Core.

Un serveur web a un nombre limité de threads disponibles et, dans les situations de forte charge, tous les threads disponibles peuvent être utilisés.A web server has a limited number of threads available, and in high load situations all of the available threads might be in use. Quand cela se produit, le serveur ne peut pas traiter de nouvelle requête tant que les threads ne sont pas libérés.When that happens, the server can't process new requests until the threads are freed up. Avec le code synchrone, plusieurs threads peuvent être bloqués alors qu’ils n’effectuent en fait aucun travail, car ils attendent que des E/S se terminent.With synchronous code, many threads may be tied up while they aren't actually doing any work because they're waiting for I/O to complete. Avec le code asynchrone, quand un processus attend que des E/S se terminent, son thread est libéré afin d’être utilisé par le serveur pour traiter d’autres demandes.With asynchronous code, when a process is waiting for I/O to complete, its thread is freed up for the server to use for processing other requests. Il permet ainsi d’utiliser les ressources serveur plus efficacement, et le serveur peut gérer plus de trafic sans retard.As a result, asynchronous code enables server resources to be used more efficiently, and the server can handle more traffic without delays.

Le code asynchrone introduit néanmoins une petite surcharge au moment de l’exécution.Asynchronous code does introduce a small amount of overhead at run time. Dans les situations de faible trafic, le gain de performances est négligeable, tandis qu’en cas de trafic élevé l’amélioration potentielle des performances est importante.For low traffic situations, the performance hit is negligible, while for high traffic situations, the potential performance improvement is substantial.

Dans le code suivant, le mot clé async, la valeur renvoyée Task<T>, le mot clé await et la méthode ToListAsync déclenchent l’exécution asynchrone du code.In the following code, the async keyword, Task<T> return value, await keyword, and ToListAsync method make the code execute asynchronously.

public async Task OnGetAsync()
{
    Students = await _context.Students.ToListAsync();
}
  • Le mot clé async fait en sorte que le compilateur :The async keyword tells the compiler to:
    • Génère des rappels pour les parties du corps de méthode.Generate callbacks for parts of the method body.
    • Crée l’objet Task qui est retourné.Create the Task object that's returned.
  • Le type de retour Task<T> représente le travail en cours.The Task<T> return type represents ongoing work.
  • Le mot clé await indique au compilateur de fractionner la méthode en deux parties.The await keyword causes the compiler to split the method into two parts. La première partie se termine par l’opération qui est démarrée de façon asynchrone.The first part ends with the operation that's started asynchronously. La seconde partie est placée dans une méthode de rappel qui est appelée quand l’opération se termine.The second part is put into a callback method that's called when the operation completes.
  • ToListAsync est la version asynchrone de la méthode d’extension ToList.ToListAsync is the asynchronous version of the ToList extension method.

Voici quelques éléments à connaître lors de l’écriture de code asynchrone qui utilise EF Core :Some things to be aware of when writing asynchronous code that uses EF Core:

  • Seules les instructions qui provoquent l’envoi de requêtes ou de commandes vers la base de données sont exécutées de façon asynchrone.Only statements that cause queries or commands to be sent to the database are executed asynchronously. Cela inclut ToListAsync, SingleOrDefaultAsync, FirstOrDefaultAsync et SaveChangesAsync,That includes ToListAsync, SingleOrDefaultAsync, FirstOrDefaultAsync, and SaveChangesAsync. mais pas les instructions qui ne font que changer un IQueryable, telles que var students = context.Students.Where(s => s.LastName == "Davolio").It doesn't include statements that just change an IQueryable, such as var students = context.Students.Where(s => s.LastName == "Davolio").
  • Un contexte EF Core n’est pas thread-safe : n’essayez pas d’effectuer plusieurs opérations en parallèle.An EF Core context isn't thread safe: don't try to do multiple operations in parallel.
  • Pour tirer parti des avantages de performances du code asynchrone, vérifiez que les packages de bibliothèque (par exemple pour la pagination) utilisent le mode asynchrone s’ils appellent des méthodes EF Core qui envoient des requêtes à la base de données.To take advantage of the performance benefits of async code, verify that library packages (such as for paging) use async if they call EF Core methods that send queries to the database.

Pour plus d’informations sur la programmation asynchrone dans .NET, consultez Vue d’ensemble d’Async et Programmation asynchrone avec async et await.For more information about asynchronous programming in .NET, see Async Overview and Asynchronous programming with async and await.

Étapes suivantesNext steps

L’exemple d’application web Contoso University montre comment créer une application web Razor Pages ASP.NET Core à l’aide d’Entity Framework (EF) Core.The Contoso University sample web app demonstrates how to create an ASP.NET Core Razor Pages app using Entity Framework (EF) Core.

L’exemple d’application est un site web pour une université Contoso fictive.The sample app is a web site for a fictional Contoso University. Il comprend des fonctionnalités telles que l’admission des étudiants, la création des cours et les affectations des formateurs.It includes functionality such as student admission, course creation, and instructor assignments. Cette page est la première d’une série de didacticiels qui expliquent comment générer l’exemple d’application Contoso University.This page is the first in a series of tutorials that explain how to build the Contoso University sample app.

Télécharger ou afficher l’application terminée.Download or view the completed app. Télécharger les instructions.Download instructions.

PrérequisPrerequisites

Visual Studio 2019 avec les charges de travail suivantes :Visual Studio 2019 with the following workloads:

  • Développement web et ASP.NETASP.NET and web development
  • Développement multiplateforme .NET Core.NET Core cross-platform development

Connaissance des Pages Razor.Familiarity with Razor Pages. Les programmeurs débutants doivent lire Bien démarrer avec les pages Razor avant de démarrer cette série.New programmers should complete Get started with Razor Pages before starting this series.

Résolution des problèmesTroubleshooting

Si vous rencontrez un problème que vous ne pouvez pas résoudre, vous pouvez généralement trouver la solution en comparant votre code au projet terminé.If you run into a problem you can't resolve, you can generally find the solution by comparing your code to the completed project. Un bon moyen d’obtenir de l’aide est de publier une question sur StackOverflow.com pour ASP.NET Core ou EF Core.A good way to get help is by posting a question to StackOverflow.com for ASP.NET Core or EF Core.

L’application web Contoso UniversityThe Contoso University web app

L’application générée dans ces didacticiels est le site web de base d’une université.The app built in these tutorials is a basic university web site.

Les utilisateurs peuvent afficher et mettre à jour les informations relatives aux étudiants, aux cours et aux formateurs.Users can view and update student, course, and instructor information. Voici quelques-uns des écrans créés dans le didacticiel.Here are a few of the screens created in the tutorial.

Page d’index des étudiants

Page de modification des étudiants

Le style de l’interface utilisateur de ce site est proche de ce qui est généré par les modèles prédéfinis.The UI style of this site is close to what's generated by the built-in templates. Le didacticiel est axé sur Core EF avec des pages Razor, et non sur l’interface utilisateur.The tutorial focus is on EF Core with Razor Pages, not the UI.

Créer l’application web Razor Pages ContosoUniversityCreate the ContosoUniversity Razor Pages web app

  • Dans Visual Studio, dans le menu Fichier, sélectionnez Nouveau > Projet.From the Visual Studio File menu, select New > Project.
  • Créez une application web ASP.NET Core.Create a new ASP.NET Core Web Application. Nommez le projet ContosoUniversity.Name the project ContosoUniversity. Il est important de nommer le projet ContosoUniversity afin que les espaces de noms correspondent quand le code est copié/collé.It's important to name the project ContosoUniversity so the namespaces match when code is copy/pasted.
  • Sélectionnez ASP.NET Core 2.1 dans la liste déroulante, puis sélectionnez Application web.Select ASP.NET Core 2.1 in the dropdown, and then select Web Application.

Pour les images des étapes précédentes, consultez Créer une application web Razor.For images of the preceding steps, see Create a Razor web app. Exécutez l'application.Run the app.

Configurer le style du siteSet up the site style

Quelques changements permettent de définir le menu, la disposition et la page d’accueil du site.A few changes set up the site menu, layout, and home page. Mettez à jour Pages/Shared/_Layout.cshtml avec les changements suivants :Update Pages/Shared/_Layout.cshtml with the following changes:

  • Remplacez chaque occurrence de « ContosoUniversity » par « Contoso University ».Change each occurrence of "ContosoUniversity" to "Contoso University". Il y a trois occurrences.There are three occurrences.

  • Ajoutez des entrées de menu pour Students, Courses, Instructors et Departments, et supprimez l’entrée de menu Contact.Add menu entries for Students, Courses, Instructors, and Departments, and delete the Contact menu entry.

Les modifications sont mises en surbrillance.The changes are highlighted. (Tout le balisage n’est pas affiché.)(All the markup is not displayed.)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] : Contoso University</title>

    <environment include="Development">
        <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
        <link rel="stylesheet" href="~/css/site.css" />
    </environment>
    <environment exclude="Development">
        <link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
              asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
              asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
        <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
    </environment>
</head>
<body>
    <nav class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a asp-page="/Index" class="navbar-brand">Contoso University</a>
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li><a asp-page="/Index">Home</a></li>
                    <li><a asp-page="/About">About</a></li>
                    <li><a asp-page="/Students/Index">Students</a></li>
                    <li><a asp-page="/Courses/Index">Courses</a></li>
                    <li><a asp-page="/Instructors/Index">Instructors</a></li>
                    <li><a asp-page="/Departments/Index">Departments</a></li>
                </ul>
            </div>
        </div>
    </nav>

    <partial name="_CookieConsentPartial" />

    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; 2018 : Contoso University</p>
        </footer>
    </div>

    @*Remaining markup not shown for brevity.*@

Dans Pages/Index.cshtml, remplacez le contenu du fichier par le code suivant afin de remplacer le texte sur ASP.NET et MVC par le texte concernant cette application :In Pages/Index.cshtml, replace the contents of the file with the following code to replace the text about ASP.NET and MVC with text about this app:

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<div class="jumbotron">
    <h1>Contoso University</h1>
</div>
<div class="row">
    <div class="col-md-4">
        <h2>Welcome to Contoso University</h2>
        <p>
            Contoso University is a sample application that
            demonstrates how to use Entity Framework Core in an
            ASP.NET Core Razor Pages web app.
        </p>
    </div>
    <div class="col-md-4">
        <h2>Build it from scratch</h2>
        <p>You can build the application by following the steps in a series of tutorials.</p>
        <p>
            <a class="btn btn-default"
               href="https://docs.microsoft.com/aspnet/core/data/ef-rp/intro">
                See the tutorial &raquo;
            </a>
        </p>
    </div>
    <div class="col-md-4">
        <h2>Download it</h2>
        <p>You can download the completed project from GitHub.</p>
        <p>
            <a class="btn btn-default"
               href="https://github.com/dotnet/AspNetCore.Docs/tree/master/aspnetcore/data/ef-rp/intro/samples/">
                See project source code &raquo;
            </a>
        </p>
    </div>
</div>

Créer le modèle de donnéesCreate the data model

Créez des classes d’entités pour l’application Contoso University.Create entity classes for the Contoso University app. Commencez par les trois entités suivantes :Start with the following three entities:

Diagramme du modèle de données Course-Enrollment-Student

Il existe une relation un-à-plusieurs entre les entités Student et Enrollment.There's a one-to-many relationship between Student and Enrollment entities. Il existe une relation un-à-plusieurs entre les entités Course et Enrollment.There's a one-to-many relationship between Course and Enrollment entities. Un étudiant peut s’inscrire à autant de cours qu’il le souhaite.A student can enroll in any number of courses. Un cours peut avoir une quantité illimitée d’élèves inscrits.A course can have any number of students enrolled in it.

Dans les sections suivantes, une classe pour chacune de ces entités est créée.In the following sections, a class for each one of these entities is created.

L’entité StudentThe Student entity

Diagramme de l’entité Student

Créez un dossier Models.Create a Models folder. Dans le dossier Models, créez un fichier de classe nommé Student.cs avec le code suivant :In the Models folder, create a class file named Student.cs with the following code:

using System;
using System.Collections.Generic;

namespace ContosoUniversity.Models
{
    public class Student
    {
        public int ID { get; set; }
        public string LastName { get; set; }
        public string FirstMidName { get; set; }
        public DateTime EnrollmentDate { get; set; }

        public ICollection<Enrollment> Enrollments { get; set; }
    }
}

La propriété ID devient la colonne de clé primaire de la table de base de données qui correspond à cette classe.The ID property becomes the primary key column of the database (DB) table that corresponds to this class. Par défaut, EF Core interprète une propriété nommée ID ou classnameID comme clé primaire.By default, EF Core interprets a property that's named ID or classnameID as the primary key. Dans classnameID, classname est le nom de la classe.In classnameID, classname is the name of the class. L’autre clé primaire reconnue automatiquement est StudentID dans l’exemple précédent.The alternative automatically recognized primary key is StudentID in the preceding example.

La Enrollments propriété est une propriété de navigation.The Enrollments property is a navigation property. Les propriétés de navigation établissent des liaisons à d’autres entités qui sont associées à cette entité.Navigation properties link to other entities that are related to this entity. Ici, la propriété Enrollments d’un Student entity contient toutes les entités Enrollment associées à ce Student.In this case, the Enrollments property of a Student entity holds all of the Enrollment entities that are related to that Student. Par exemple, si une ligne Student dans la base de données a deux lignes Enrollment associées, la propriété de navigation Enrollments contient ces deux entités Enrollment.For example, if a Student row in the DB has two related Enrollment rows, the Enrollments navigation property contains those two Enrollment entities. Une ligne Enrollment associée est une ligne qui contient la valeur de clé primaire de cette étudiant dans la colonne StudentID.A related Enrollment row is a row that contains that student's primary key value in the StudentID column. Par exemple, supposez que l’étudiant avec ID=1 a deux lignes dans la table Enrollment.For example, suppose the student with ID=1 has two rows in the Enrollment table. La table Enrollment a deux lignes avec StudentID = 1.The Enrollment table has two rows with StudentID = 1. StudentID est une clé étrangère dans la table Enrollment qui spécifie l’étudiant dans la table Student.StudentID is a foreign key in the Enrollment table that specifies the student in the Student table.

Si une propriété de navigation peut contenir plusieurs entités, la propriété de navigation doit être un type de liste, tel que ICollection<T>.If a navigation property can hold multiple entities, the navigation property must be a list type, such as ICollection<T>. Vous pouvez spécifier ICollection<T>, ou un type tel que List<T> ou HashSet<T>.ICollection<T> can be specified, or a type such as List<T> or HashSet<T>. Quand vous utilisez ICollection<T>, EF Core crée une collection HashSet<T> par défaut.When ICollection<T> is used, EF Core creates a HashSet<T> collection by default. Les propriétés de navigation qui contiennent plusieurs entités proviennent de relations plusieurs-à-plusieurs et un-à-plusieurs.Navigation properties that hold multiple entities come from many-to-many and one-to-many relationships.

L’entité EnrollmentThe Enrollment entity

Diagramme de l’entité Enrollment

Dans le dossier Models, créez un fichier Enrollment.cs avec le code suivant :In the Models folder, create Enrollment.cs with the following code:

namespace ContosoUniversity.Models
{
    public enum Grade
    {
        A, B, C, D, F
    }

    public class Enrollment
    {
        public int EnrollmentID { get; set; }
        public int CourseID { get; set; }
        public int StudentID { get; set; }
        public Grade? Grade { get; set; }

        public Course Course { get; set; }
        public Student Student { get; set; }
    }
}

La propriété EnrollmentID est la clé primaire.The EnrollmentID property is the primary key. Cette entité utilise le modèle classnameID au lieu de ID comme l’entité Student.This entity uses the classnameID pattern instead of ID like the Student entity. En général, les développeurs choisissent un modèle et l’utilisent dans tout le modèle de données.Typically developers choose one pattern and use it throughout the data model. Dans un prochain didacticiel, nous verrons qu’utiliser ID sans classname simplifie l’implémentation de l’héritage dans le modèle de données.In a later tutorial, using ID without classname is shown to make it easier to implement inheritance in the data model.

La propriété Grade est un enum.The Grade property is an enum. Le point d’interrogation après la déclaration de type Grade indique que la propriété Grade est nullable.The question mark after the Grade type declaration indicates that the Grade property is nullable. Une note (Grade) qui a la valeur Null est différente d’une note égale à zéro : la valeur Null signifie qu’une note n’est pas connue ou n’a pas encore été affectée.A grade that's null is different from a zero grade -- null means a grade isn't known or hasn't been assigned yet.

La propriété StudentID est une clé étrangère, et la propriété de navigation correspondante est Student.The StudentID property is a foreign key, and the corresponding navigation property is Student. Une entité Enrollment est associée à une entité Student. Par conséquent, la propriété contient une seule entité Student.An Enrollment entity is associated with one Student entity, so the property contains a single Student entity. L’entité Student diffère de la propriété de navigation Student.Enrollments, qui contient plusieurs entités Enrollment.The Student entity differs from the Student.Enrollments navigation property, which contains multiple Enrollment entities.

La propriété CourseID est une clé étrangère, et la propriété de navigation correspondante est Course.The CourseID property is a foreign key, and the corresponding navigation property is Course. Une entité Enrollment est associée à une entité Course.An Enrollment entity is associated with one Course entity.

EF Core interprète une propriété en tant que clé étrangère si elle se nomme <navigation property name><primary key property name>.EF Core interprets a property as a foreign key if it's named <navigation property name><primary key property name>. Par exemple, StudentID pour la propriété de navigation Student, puisque la clé primaire de l’entité Student est ID.For example,StudentID for the Student navigation property, since the Student entity's primary key is ID. Les propriétés de clé étrangère peuvent également se nommer <primary key property name>.Foreign key properties can also be named <primary key property name>. Par exemple, CourseID puisque la clé primaire de l’entité Course est CourseID.For example, CourseID since the Course entity's primary key is CourseID.

L’entité CourseThe Course entity

Diagramme de l’entité Course

Dans le dossier Models, créez un fichier Course.cs avec le code suivant :In the Models folder, create Course.cs with the following code:

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;

namespace ContosoUniversity.Models
{
    public class Course
    {
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int CourseID { get; set; }
        public string Title { get; set; }
        public int Credits { get; set; }

        public ICollection<Enrollment> Enrollments { get; set; }
    }
}

La propriété Enrollments est une propriété de navigation.The Enrollments property is a navigation property. Une entité Course peut être associée à un nombre quelconque d’entités Enrollment.A Course entity can be related to any number of Enrollment entities.

L’attribut DatabaseGenerated permet à l’application de spécifier la clé primaire, plutôt que de la faire générer par la base de données.The DatabaseGenerated attribute allows the app to specify the primary key rather than having the DB generate it.

Générer automatiquement le modèle d’étudiantScaffold the student model

Dans cette section, le modèle d’étudiant est généré automatiquement.In this section, the student model is scaffolded. Autrement dit, l’outil de génération de modèles automatique génère des pages pour les opérations de création (Create), de lecture (Read), de mise à jour (Update) et de suppression (Delete) (CRUD) pour le modèle d’étudiant.That is, the scaffolding tool produces pages for Create, Read, Update, and Delete (CRUD) operations for the student model.

  • Créez le projet.Build the project.
  • Créez le dossier Pages/Students.Create the Pages/Students folder.
  • Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le dossier Pages/Students > Ajouter > Nouvel élément généré automatiquement.In Solution Explorer, right click on the Pages/Students folder > Add > New Scaffolded Item.
  • Dans le dialogue Ajouter l’échafaudage, sélectionnez les pages Razor à l’aide de l’entité Cadre (CRUD) > ADD.In the Add Scaffold dialog, select Razor Pages using Entity Framework (CRUD) > ADD.

Renseignez la boîte de dialogue Pages Razor avec Entity Framework (CRUD) :Complete the Add Razor Pages using Entity Framework (CRUD) dialog:

  • Dans la liste déroulante Classe de modèle, sélectionnez Student (ContosoUniversity.Models).In the Model class drop-down, select Student (ContosoUniversity.Models).
  • Dans la ligne Classe de contexte de données, sélectionnez le signe + (plus) et remplacez le nom généré par ContosoUniversity.Models.SchoolContext.In the Data context class row, select the + (plus) sign and change the generated name to ContosoUniversity.Models.SchoolContext.
  • Dans la liste déroulante Classe de contexte de données, sélectionnez ContosoUniversity.Models.SchoolContextIn the Data context class drop-down, select ContosoUniversity.Models.SchoolContext
  • Sélectionnez Ajouter.Select Add.

Boîte de dialogue CRUD

Consultez Générer automatiquement le modèle de film si vous rencontrez un problème à l’étape précédente.See Scaffold the movie model if you have a problem with the preceding step.

Le processus de génération de modèles automatique a créé et changé les fichiers suivants :The scaffold process created and changed the following files:

Fichiers créésFiles created

  • Pages/Students Create, Delete, Details, Edit, Index.Pages/Students Create, Delete, Details, Edit, Index.
  • Data/SchoolContext.csData/SchoolContext.cs

Mises à jour du fichierFile updates

  • Startup.cs : Les changements apportés à ce fichier sont détaillés dans la section suivante.Startup.cs : Changes to this file are detailed in the next section.
  • appSettings.JSON : La chaîne de connexion utilisée pour se connecter à une base de données locale est ajoutée.appsettings.json : The connection string used to connect to a local database is added.

Examiner le contexte inscrit avec l’injection de dépendancesExamine the context registered with dependency injection

ASP.NET Core comprend l’injection de dépendances.ASP.NET Core is built with dependency injection. Des services (tels que le contexte de base de données EF Core) sont inscrits avec l’injection de dépendances au démarrage de l’application.Services (such as the EF Core DB context) are registered with dependency injection during application startup. Ces services sont affectés aux composants qui les nécessitent (par exemple les Pages Razor) par le biais de paramètres de constructeur.Components that require these services (such as Razor Pages) are provided these services via constructor parameters. Le code du constructeur qui obtient une instance de contexte de base de données est indiqué plus loin dans le didacticiel.The constructor code that gets a db context instance is shown later in the tutorial.

L’outil de génération de modèles automatique a créé automatiquement un contexte de base de données et l’a inscrit dans le conteneur d’injection de dépendances.The scaffolding tool automatically created a DB Context and registered it with the dependency injection container.

Examinez la méthode ConfigureServices dans Startup.cs.Examine the ConfigureServices method in Startup.cs. La ligne en surbrillance a été ajoutée par l’outil de génération de modèles automatique :The highlighted line was added by the scaffolder:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        // This lambda determines whether user consent for 
        //non -essential cookies is needed for a given request.
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    services.AddDbContext<SchoolContext>(options =>
       options.UseSqlServer(Configuration.GetConnectionString("SchoolContext")));
}

Le nom de la chaîne de connexion est transmis au contexte en appelant une méthode sur un objet DbContextOptions.The name of the connection string is passed in to the context by calling a method on a DbContextOptions object. Pour le développement local, le système de configuration ASP.NET Core lit la chaîne de connexion à partir du fichier appsettings.json.For local development, the ASP.NET Core configuration system reads the connection string from the appsettings.json file.

Mettre à jour la méthode MainUpdate main

Dans Program.cs, modifiez la méthode Main pour effectuer les opérations suivantes :In Program.cs, modify the Main method to do the following:

  • Obtenir une instance de contexte de base de données à partir du conteneur d’injection de dépendances.Get a DB context instance from the dependency injection container.
  • Appelez EnsureCreated.Call the EnsureCreated.
  • Supprimez le contexte une fois la méthode EnsureCreated exécutée.Dispose the context when the EnsureCreated method completes.

Le code suivant montre le fichier Program.cs mis à jour.The following code shows the updated Program.cs file.

using ContosoUniversity.Models;                   // SchoolContext
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;   // CreateScope
using Microsoft.Extensions.Logging;
using System;

namespace ContosoUniversity
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var host = CreateWebHostBuilder(args).Build();

            using (var scope = host.Services.CreateScope())
            {
                var services = scope.ServiceProvider;

                try
                {
                    var context = services.GetRequiredService<SchoolContext>();
                    context.Database.EnsureCreated();
                }
                catch (Exception ex)
                {
                    var logger = services.GetRequiredService<ILogger<Program>>();
                    logger.LogError(ex, "An error occurred creating the DB.");
                }
            }

            host.Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>();
    }
}

EnsureCreated garantit que la base de données existe pour le contexte.EnsureCreated ensures that the database for the context exists. Si elle existe, aucune action n’est effectuée.If it exists, no action is taken. Si elle n’existe pas, la base de données et tous ses schéma sont créés.If it does not exist, then the database and all its schema are created. EnsureCreated n’utilise pas de migrations pour créer la base de données.EnsureCreated does not use migrations to create the database. Une base de données créée avec EnsureCreated ne peut pas être mise à jour à l’aide de migrations par la suite.A database that is created with EnsureCreated cannot be later updated using migrations.

EnsureCreated est appelée au démarrage de l’application, ce qui active le flux de travail suivant :EnsureCreated is called on app start, which allows the following work flow:

  • Supprimez la base de données.Delete the DB.
  • Modification du schéma de base de données (par exemple, ajout d’un champ EmailAddress).Change the DB schema (for example, add an EmailAddress field).
  • Exécutez l'application.Run the app.
  • EnsureCreated crée une base de données avec la colonne EmailAddress.EnsureCreated creates a DB with theEmailAddress column.

EnsureCreated est pratique au début du développement quand le schéma évolue rapidement.EnsureCreated is convenient early in development when the schema is rapidly evolving. Plus loin dans le tutoriel, la base de données est supprimée et les migrations sont utilisées.Later in the tutorial the DB is deleted and migrations are used.

Test de l'applicationTest the app

Exécutez l’application et acceptez la politique de cookies.Run the app and accept the cookie policy. Cette application ne conserve pas les informations personnelles.This app doesn't keep personal information. Vous pouvez en savoir plus sur la politique de cookies à la section Prise en charge du règlement général sur la protection des données (RGPD).You can read about the cookie policy at EU General Data Protection Regulation (GDPR) support.

  • Sélectionnez le lien Students, puis Créer nouveau.Select the Students link and then Create New.
  • Testez les liens Edit, Details et Delete.Test the Edit, Details, and Delete links.

Examiner le contexte de base de données SchoolContextExamine the SchoolContext DB context

La classe principale qui coordonne les fonctionnalités d’EF Core pour un modèle de données spécifié est la classe de contexte de base de données.The main class that coordinates EF Core functionality for a given data model is the DB context class. Le contexte de données est dérivé de Microsoft.EntityFrameworkCore.DbContext.The data context is derived from Microsoft.EntityFrameworkCore.DbContext. Il spécifie les entités qui sont incluses dans le modèle de données.The data context specifies which entities are included in the data model. Dans ce projet, la classe est nommée SchoolContext.In this project, the class is named SchoolContext.

Mettez à jour SchoolContext.cs avec le code suivant :Update SchoolContext.cs with the following code:

using Microsoft.EntityFrameworkCore;

namespace ContosoUniversity.Models
{
    public class SchoolContext : DbContext
    {
        public SchoolContext(DbContextOptions<SchoolContext> options)
            : base(options)
        {
        }

        public DbSet<Student> Student { get; set; }
        public DbSet<Enrollment> Enrollment { get; set; }
        public DbSet<Course> Course { get; set; }
    }
}

Le code en surbrillance crée une propriété DbSet<TEntity> pour chaque jeu d’entités.The highlighted code creates a DbSet<TEntity> property for each entity set. Dans la terminologie d’EF Core :In EF Core terminology:

  • Un jeu d’entités correspond généralement à une table de base de données.An entity set typically corresponds to a DB table.
  • Une entité correspond à une ligne dans la table.An entity corresponds to a row in the table.

DbSet<Enrollment> et DbSet<Course> peuvent être omis.DbSet<Enrollment> and DbSet<Course> could be omitted. EF Core les inclut implicitement, car l’entité Student référence l’entité Enrollment, et l’entité Enrollment référence l’entité Course.EF Core includes them implicitly because the Student entity references the Enrollment entity, and the Enrollment entity references the Course entity. Pour ce didacticiel, conservez DbSet<Enrollment> et DbSet<Course> dans le SchoolContext.For this tutorial, keep DbSet<Enrollment> and DbSet<Course> in the SchoolContext.

Base de données locale SQL Server ExpressSQL Server Express LocalDB

La chaîne de connexion spécifie SQL Server LocalDB.The connection string specifies SQL Server LocalDB. LocalDB est une version allégée du moteur de base de données SQL Server Express. Elle est destinée au développement d’applications, et non à une utilisation en production.LocalDB is a lightweight version of the SQL Server Express Database Engine and is intended for app development, not production use. LocalDB démarre à la demande et s’exécute en mode utilisateur, ce qui n’implique aucune configuration complexe.LocalDB starts on demand and runs in user mode, so there's no complex configuration. Par défaut, LocalDB crée des fichiers de base de données .mdf dans le répertoire C:/Users/<user>.By default, LocalDB creates .mdf DB files in the C:/Users/<user> directory.

Ajouter du code pour initialiser la base de données avec des données de testAdd code to initialize the DB with test data

EF Core crée une base de données vide.EF Core creates an empty DB. Dans cette section, une méthode Initialize est écrite pour la remplir avec des données de test.In this section, an Initialize method is written to populate it with test data.

Dans le dossier Data, créez un fichier de classe nommé DbInitializer.cs et ajoutez le code suivant :In the Data folder, create a new class file named DbInitializer.cs and add the following code:

using ContosoUniversity.Models;
using System;
using System.Linq;

namespace ContosoUniversity.Models
{
    public static class DbInitializer
    {
        public static void Initialize(SchoolContext context)
        {
            context.Database.EnsureCreated();

            // Look for any students.
            if (context.Student.Any())
            {
                return;   // DB has been seeded
            }

            var students = new Student[]
            {
            new Student{FirstMidName="Carson",LastName="Alexander",EnrollmentDate=DateTime.Parse("2005-09-01")},
            new Student{FirstMidName="Meredith",LastName="Alonso",EnrollmentDate=DateTime.Parse("2002-09-01")},
            new Student{FirstMidName="Arturo",LastName="Anand",EnrollmentDate=DateTime.Parse("2003-09-01")},
            new Student{FirstMidName="Gytis",LastName="Barzdukas",EnrollmentDate=DateTime.Parse("2002-09-01")},
            new Student{FirstMidName="Yan",LastName="Li",EnrollmentDate=DateTime.Parse("2002-09-01")},
            new Student{FirstMidName="Peggy",LastName="Justice",EnrollmentDate=DateTime.Parse("2001-09-01")},
            new Student{FirstMidName="Laura",LastName="Norman",EnrollmentDate=DateTime.Parse("2003-09-01")},
            new Student{FirstMidName="Nino",LastName="Olivetto",EnrollmentDate=DateTime.Parse("2005-09-01")}
            };
            foreach (Student s in students)
            {
                context.Student.Add(s);
            }
            context.SaveChanges();

            var courses = new Course[]
            {
            new Course{CourseID=1050,Title="Chemistry",Credits=3},
            new Course{CourseID=4022,Title="Microeconomics",Credits=3},
            new Course{CourseID=4041,Title="Macroeconomics",Credits=3},
            new Course{CourseID=1045,Title="Calculus",Credits=4},
            new Course{CourseID=3141,Title="Trigonometry",Credits=4},
            new Course{CourseID=2021,Title="Composition",Credits=3},
            new Course{CourseID=2042,Title="Literature",Credits=4}
            };
            foreach (Course c in courses)
            {
                context.Course.Add(c);
            }
            context.SaveChanges();

            var enrollments = new Enrollment[]
            {
            new Enrollment{StudentID=1,CourseID=1050,Grade=Grade.A},
            new Enrollment{StudentID=1,CourseID=4022,Grade=Grade.C},
            new Enrollment{StudentID=1,CourseID=4041,Grade=Grade.B},
            new Enrollment{StudentID=2,CourseID=1045,Grade=Grade.B},
            new Enrollment{StudentID=2,CourseID=3141,Grade=Grade.F},
            new Enrollment{StudentID=2,CourseID=2021,Grade=Grade.F},
            new Enrollment{StudentID=3,CourseID=1050},
            new Enrollment{StudentID=4,CourseID=1050},
            new Enrollment{StudentID=4,CourseID=4022,Grade=Grade.F},
            new Enrollment{StudentID=5,CourseID=4041,Grade=Grade.C},
            new Enrollment{StudentID=6,CourseID=1045},
            new Enrollment{StudentID=7,CourseID=3141,Grade=Grade.A},
            };
            foreach (Enrollment e in enrollments)
            {
                context.Enrollment.Add(e);
            }
            context.SaveChanges();
        }
    }
}

Remarque : Le Models code précédent utilisenamespace ContosoUniversity.Modelspour Datal’espace de nom ( ) plutôt que .Note: The preceding code uses Models for the namespace (namespace ContosoUniversity.Models) rather than Data. Models est cohérent avec le code généré par l’outil de génération de modèles automatique.Models is consistent with the scaffolder-generated code. Pour plus d’informations, consultez ce problème de génération de modèles automatique GitHub.For more information, see this GitHub scaffolding issue.

Le code vérifie s’il existe des étudiants dans la base de données.The code checks if there are any students in the DB. S’il n’y en a pas, la base de données est initialisée avec des données de test.If there are no students in the DB, the DB is initialized with test data. Il charge les données de test dans des tableaux plutôt que des collections List<T> afin d’optimiser les performances.It loads test data into arrays rather than List<T> collections to optimize performance.

La méthode EnsureCreated crée automatiquement la base de données pour le contexte de base de données.The EnsureCreated method automatically creates the DB for the DB context. Si la base de données existe, EnsureCreated retourne sans modifier la base de données.If the DB exists, EnsureCreated returns without modifying the DB.

Dans Program.cs, modifiez la méthode Main pour appeler Initialize :In Program.cs, modify the Main method to call Initialize:

public class Program
{
    public static void Main(string[] args)
    {
        var host = CreateWebHostBuilder(args).Build();

        using (var scope = host.Services.CreateScope())
        {
            var services = scope.ServiceProvider;

            try
            {
                var context = services.GetRequiredService<SchoolContext>();
                // using ContosoUniversity.Data; 
                DbInitializer.Initialize(context);
            }
            catch (Exception ex)
            {
                var logger = services.GetRequiredService<ILogger<Program>>();
                logger.LogError(ex, "An error occurred creating the DB.");
            }
        }

        host.Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

Arrêtez l’application si elle est en cours d’exécution et exécutez la commande suivante dans la Console du gestionnaire de package :Stop the app if it's running, and run the following command in the Package Manager Console (PMC):

Drop-Database

Afficher la base de donnéesView the DB

Le nom de la base de données est généré à partir du nom de contexte indiqué précédemment, ainsi que d’un tiret et d’un GUID.The database name is generated from the context name you provided earlier plus a dash and a GUID. Il sera donc « SchoolContext-{GUID} ».Thus, the database name will be "SchoolContext-{GUID}". Le GUID est différent pour chaque utilisateur.The GUID will be different for each user. Ouvrez l’Explorateur d’objets SQL Server (SSOX) à partir du menu Affichage de Visual Studio.Open SQL Server Object Explorer (SSOX) from the View menu in Visual Studio. Dans SSOX, cliquez sur (localdb)\MSSQLLocalDB > Databases > SchoolContext-{GUID}.In SSOX, click (localdb)\MSSQLLocalDB > Databases > SchoolContext-{GUID}.

Développez le nœud Tables.Expand the Tables node.

Cliquez avec le bouton droit sur la table Student et cliquez sur Afficher les données pour voir les colonnes créées et les lignes insérées dans la table.Right-click the Student table and click View Data to see the columns created and the rows inserted into the table.

Code asynchroneAsynchronous code

La programmation asynchrone est le mode par défaut pour ASP.NET Core et EF Core.Asynchronous programming is the default mode for ASP.NET Core and EF Core.

Un serveur web a un nombre limité de threads disponibles et, dans les situations de forte charge, tous les threads disponibles peuvent être utilisés.A web server has a limited number of threads available, and in high load situations all of the available threads might be in use. Quand cela se produit, le serveur ne peut pas traiter de nouvelle requête tant que les threads ne sont pas libérés.When that happens, the server can't process new requests until the threads are freed up. Avec le code synchrone, plusieurs threads peuvent être bloqués alors qu’ils n’effectuent en fait aucun travail, car ils attendent que des E/S se terminent.With synchronous code, many threads may be tied up while they aren't actually doing any work because they're waiting for I/O to complete. Avec le code asynchrone, quand un processus attend que des E/S se terminent, son thread est libéré afin d’être utilisé par le serveur pour traiter d’autres demandes.With asynchronous code, when a process is waiting for I/O to complete, its thread is freed up for the server to use for processing other requests. Il permet ainsi d’utiliser les ressources serveur plus efficacement, et le serveur peut gérer plus de trafic sans retard.As a result, asynchronous code enables server resources to be used more efficiently, and the server is enabled to handle more traffic without delays.

Le code asynchrone introduit néanmoins une petite surcharge au moment de l’exécution.Asynchronous code does introduce a small amount of overhead at run time. Dans les situations de faible trafic, le gain de performances est négligeable, tandis qu’en cas de trafic élevé l’amélioration potentielle des performances est importante.For low traffic situations, the performance hit is negligible, while for high traffic situations, the potential performance improvement is substantial.

Dans le code suivant, le mot clé async, la valeur renvoyée Task<T>, le mot clé await et la méthode ToListAsync déclenchent l’exécution asynchrone du code.In the following code, the async keyword, Task<T> return value, await keyword, and ToListAsync method make the code execute asynchronously.

public async Task OnGetAsync()
{
    Student = await _context.Student.ToListAsync();
}
  • Le mot clé async fait en sorte que le compilateur :The async keyword tells the compiler to:

    • Génère des rappels pour les parties du corps de méthode.Generate callbacks for parts of the method body.
    • Crée automatiquement l’objet Task qui est retourné.Automatically create the Task object that's returned. Pour plus d’informations, consultez Type de retour Task.For more information, see Task Return Type.
  • Le type de retour implicite Task représente le travail en cours.The implicit return type Task represents ongoing work.

  • Le mot clé await indique au compilateur de fractionner la méthode en deux parties.The await keyword causes the compiler to split the method into two parts. La première partie se termine par l’opération qui est démarrée de façon asynchrone.The first part ends with the operation that's started asynchronously. La seconde partie est placée dans une méthode de rappel qui est appelée quand l’opération se termine.The second part is put into a callback method that's called when the operation completes.

  • ToListAsync est la version asynchrone de la méthode d’extension ToList.ToListAsync is the asynchronous version of the ToList extension method.

Voici quelques éléments à connaître lors de l’écriture de code asynchrone qui utilise EF Core :Some things to be aware of when writing asynchronous code that uses EF Core:

  • Seules les instructions qui provoquent l’envoi de requêtes ou de commandes vers la base de données sont exécutées de façon asynchrone.Only statements that cause queries or commands to be sent to the DB are executed asynchronously. Cela comprend ToListAsync, SingleOrDefaultAsync, FirstOrDefaultAsync et SaveChangesAsync,That includes, ToListAsync, SingleOrDefaultAsync, FirstOrDefaultAsync, and SaveChangesAsync. mais pas les instructions qui ne font que changer un IQueryable, telles que var students = context.Students.Where(s => s.LastName == "Davolio").It doesn't include statements that just change an IQueryable, such as var students = context.Students.Where(s => s.LastName == "Davolio").
  • Un contexte EF Core n’est pas thread-safe : n’essayez pas d’effectuer plusieurs opérations en parallèle.An EF Core context isn't thread safe: don't try to do multiple operations in parallel.
  • Pour tirer parti des avantages de performances du code asynchrone, vérifiez que les packages de bibliothèque (par exemple pour la pagination) utilisent le mode asynchrone s’ils appellent des méthodes EF Core qui envoient des requêtes à la base de données.To take advantage of the performance benefits of async code, verify that library packages (such as for paging) use async if they call EF Core methods that send queries to the DB.

Pour plus d’informations sur la programmation asynchrone dans .NET, consultez Vue d’ensemble d’Async et Programmation asynchrone avec async et await.For more information about asynchronous programming in .NET, see Async Overview and Asynchronous programming with async and await.

Dans le didacticiel suivant, nous allons examiner les opérations CRUD de base (créer, lire, mettre à jour, supprimer).In the next tutorial, basic CRUD (create, read, update, delete) operations are examined.

Ressources supplémentairesAdditional resources