Tutoriel : Implémenter des fonctionnalités CRUD avec Entity Framework dans ASP.NET MVC

Dans le tutoriel précédent, vous avez créé une application MVC qui stocke et affiche des données à l’aide d’Entity Framework (EF) 6 et SQL Server LocalDB. Dans ce tutoriel, vous passez en revue et personnalisez le code de création, de lecture, de mise à jour, de suppression (CRUD) que la structure MVC crée automatiquement pour vous dans les contrôleurs et les vues.

Remarque

Il est courant d’implémenter le patron Repository pour créer une couche d’abstraction entre votre contrôleur et la couche d’accès aux données. Pour conserver ces didacticiels simples et orientés vers l’apprentissage de l’utilisation d’EF 6 proprement dit, ils n’utilisent pas de référentiels. Pour plus d’informations sur l’implémentation de dépôts, consultez la carte du contenu d’accès aux données ASP.NET.

Voici des exemples de pages web que vous créez :

Capture d’écran de la page de détails de l’étudiant.

Capture d’écran de la page de création d’étudiant.

Capture d’écran de la page de suppression de l’étudiant.

Dans ce tutoriel, vous allez :

  • Créer une page Détails
  • Mettre à jour la page Create
  • Mettre à jour la méthode HttpPost Edit
  • Mettre à jour la page Delete
  • Fermer les connexions de base de données
  • Gérer les transactions

Prérequis

Créer une page Détails

Le code généré automatiquement pour la page Students Index a omis la propriété Enrollments, car cette propriété contient une collection. Sur la page Details, vous allez afficher le contenu de la collection dans une table HTML.

Dans Controllers\StudentController.cs, la méthode d’action de la Details vue utilise la méthode Find pour récupérer une seule Student entité.

public ActionResult Details(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    Student student = db.Students.Find(id);
    if (student == null)
    {
        return HttpNotFound();
    }
    return View(student);
}

La valeur de clé est passée à la méthode en tant que id paramètre et provient des données de routage dans le lien hypertexte Détails de la page Index.

Astuce : Données d’itinéraire

Les données de routage sont les données que le « model binder » a trouvées dans un segment d'URL spécifié dans la table de routage. Par exemple, la route par défaut spécifie les segments controller, action et id :

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

Dans l’URL suivante, la route par défaut associe Instructor à controller, Index à action et 1 à id ; il s’agit de valeurs de données d’itinéraire.

http://localhost:1230/Instructor/Index/1?courseID=2021

?courseID=2021 est une valeur de paramètre de requête. La liaison de modèle fonctionne également si vous transmettez id comme valeur de chaîne de requête :

http://localhost:1230/Instructor/Index?id=1&CourseID=2021

Les URL sont créées par des instructions ActionLink dans la vue Razor. Dans le code suivant, le paramètre id correspond à l’itinéraire par défaut, donc id est ajouté aux données de routage.

@Html.ActionLink("Select", "Index", new { id = item.PersonID  })

Dans le code suivant, courseID ne correspond pas à un paramètre dans l’itinéraire par défaut. Il est donc ajouté en tant que chaîne de requête.

@Html.ActionLink("Select", "Index", new { courseID = item.CourseID })

Pour créer la page de détails

  1. Ouvrez Views/Student/Details.cshtml.

    Chaque champ est affiché avec un helper DisplayFor comme montré dans l’exemple suivant :

    <dt>
        @Html.DisplayNameFor(model => model.LastName)
    </dt>
    <dd>
        @Html.DisplayFor(model => model.LastName)
    </dd>
    
  2. Après le EnrollmentDate champ et juste avant la balise de fermeture </dl> , ajoutez le code mis en surbrillance pour afficher une liste d’inscriptions, comme illustré dans l’exemple suivant :

    <dt>
                @Html.DisplayNameFor(model => model.EnrollmentDate)
            </dt>
    
            <dd>
                @Html.DisplayFor(model => model.EnrollmentDate)
            </dd>
            <dt>
                @Html.DisplayNameFor(model => model.Enrollments)
            </dt>
            <dd>
                <table class="table">
                    <tr>
                        <th>Course Title</th>
                        <th>Grade</th>
                    </tr>
                    @foreach (var item in Model.Enrollments)
                    {
                        <tr>
                            <td>
                                @Html.DisplayFor(modelItem => item.Course.Title)
                            </td>
                            <td>
                                @Html.DisplayFor(modelItem => item.Grade)
                            </td>
                        </tr>
                    }
                </table>
            </dd>
        </dl>
    </div>
    <p>
        @Html.ActionLink("Edit", "Edit", new { id = Model.ID }) |
        @Html.ActionLink("Back to List", "Index")
    </p>
    

    Si l'indentation du code est incorrecte après avoir collé le code, appuyez sur Ctrl+K, +D pour le mettre en forme.

    Ce code parcourt en boucle les entités dans la propriété de navigation Enrollments. Pour chaque entité Enrollment dans la propriété, le titre du cours et la note sont affichés. Le titre du cours est récupéré à partir de l’entité Course qui est stockée dans la propriété de navigation Course de l’entité Enrollments. Toutes ces données sont récupérées automatiquement à partir de la base de données quand elles sont nécessaires. En d’autres termes, vous utilisez le chargement différé ici. Vous n’avez pas spécifié le chargement hâtif pour la propriété de navigation Courses, de sorte que les inscriptions n’ont pas été récupérées dans la même requête qui a récupéré les étudiants. Au lieu de cela, la première fois que vous essayez d’accéder à la Enrollments propriété de navigation, une nouvelle requête est envoyée à la base de données pour récupérer les données. Vous pouvez en savoir plus sur le chargement différé et le chargement anticipé dans le didacticiel Lecture des données associées plus loin dans cette série.

  3. Ouvrez la page Détails en démarrant le programme (Ctrl+F5), en sélectionnant l'onglet Étudiants et en cliquant sur le lien Détails pour Alexander Carson. (Si vous appuyez sur Ctrl+F5 pendant que le fichier Details.cshtml est ouvert, vous obtenez une erreur HTTP 400. Cela est dû au fait que Visual Studio tente d’exécuter la page Details, mais qu’elle n’a pas été ouverte à partir d’un lien qui spécifie l’étudiant à afficher. Si cela se produit, supprimez « Student/Details » de l’URL et réessayez, ou fermez le navigateur, cliquez avec le bouton droit sur le projet, puis cliquez sur Afficher>Afficher dans le navigateur.)

    Vous voyez la liste des cours et notes pour l’étudiant sélectionné.

  4. Fermez le navigateur.

Mettre à jour la page Créer

  1. Dans Controllers\StudentController.cs, remplacez la HttpPostAttributeCreate méthode d’action par le code suivant. Ce code ajoute un try-catch bloc et supprime ID de l’attribut BindAttribute pour la méthode générée :

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "LastName, FirstMidName, EnrollmentDate")]Student student)
    {
        try
        {
            if (ModelState.IsValid)
            {
                db.Students.Add(student);
                db.SaveChanges();
                return RedirectToAction("Index");
            }
        }
        catch (DataException /* dex */)
        {
            //Log the error (uncomment dex variable name and add a line here to write a log.
            ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
        }
        return View(student);
    }
    

    Ce code ajoute l’entité Student créée par le liaisonneur de modèles ASP.NET MVC au jeu d’entités Students, puis enregistre les modifications dans la base de données. Le classeur de modèles référence la fonctionnalité d’ASP.NET MVC qui facilite l’utilisation des données envoyées par un formulaire ; un classeur de modèles convertit les valeurs de formulaire envoyées en types CLR et les passe à la méthode d’action dans des paramètres. Dans ce cas, le classeur de modèles instancie une entitéStudent en utilisant les valeurs de propriété de la collectionForm.

    Vous avez supprimé ID de l’attribut Bind, car ID est la valeur de clé primaire qui sera définie automatiquement par SQL Server lors de l’insertion de la ligne. L’entrée de l’utilisateur ne définit pas la valeur ID.

    Avertissement de sécurité : l’attribut ValidateAntiForgeryToken permet d’empêcher les attaques de falsification de requêtes intersites (CSRF). Elle nécessite une instruction correspondante Html.AntiForgeryToken() dans la vue, que vous verrez ultérieurement.

    L’attribut Bind est un moyen de se protéger contre l’over-posting dans les scénarios de création. Par exemple, supposons que l’entité Student inclut une propriété Secret que vous ne souhaitez pas que cette page web définisse.

    public class Student
    {
        public int ID { get; set; }
        public string LastName { get; set; }
        public string FirstMidName { get; set; }
        public DateTime EnrollmentDate { get; set; }
        public string Secret { get; set; }
    
        public virtual ICollection<Enrollment> Enrollments { get; set; }
    }
    

    Même si vous n’avez pas de champ Secret sur la page web, un pirate peut utiliser un outil tel que fiddler ou écrire du code JavaScript pour soumettre une valeur de formulaire Secret. Sans l’attribut BindAttribute limitant les champs utilisés par le liaisonneur de modèles lors de la création d’une instance Student, le liaisonneur de modèles récupérerait cette valeur de formulaire Secret et l’utiliserait pour créer l’instance d’entité Student. Ensuite, la valeur spécifiée par le hacker pour le champ de formulaire Secret, quelle qu’elle soit, est mise à jour dans la base de données. L’image suivante montre l’outil fiddler qui ajoute le champ Secret (avec la valeur « OverPost ») aux valeurs de formulaire publiées.

    Capture d’écran montrant l’onglet Composer. Dans le coin supérieur droit, « Execute » est entouré en rouge. Dans le coin inférieur droit, « Secret equals Over Post » est entouré en rouge.

    La valeur « OverPost » serait correctement ajoutée à la propriété Secret de la ligne insérée, même si vous n’aviez jamais prévu que la page web puisse définir cette propriété.

    Il est préférable d’utiliser le Include paramètre avec l’attribut Bind pour répertorier explicitement les champs. Il est également possible d’utiliser le Exclude paramètre pour bloquer les champs que vous souhaitez exclure. Include est plus sécurisé(e), car lorsque vous ajoutez une nouvelle propriété à l’entité, le nouveau champ n’est pas automatiquement protégé par une liste Exclude.

    Pour éviter le surpostage dans les scénarios de modification, lisez d’abord l’entité à partir de la base de données, puis appelez TryUpdateModel, en passant une liste explicite de propriétés autorisées. Il s’agit de la méthode utilisée dans ces didacticiels.

    Une autre façon d’empêcher le surpostage, que de nombreux développeurs préfèrent, consiste à utiliser des modèles d’affichage plutôt que des classes d’entité avec la liaison de modèle. Incluez seulement les propriétés que vous voulez mettre à jour dans le modèle de vue. Une fois le mécanisme de liaison de modèles MVC terminé, copiez les propriétés du modèle d’affichage dans l’instance d’entité, éventuellement à l’aide d’un outil tel que AutoMapper. Utilisez db.Entry sur l’instance d’entité pour définir son état sur Inchangé, puis définissez Property(« PropertyName »).IsModified à true sur chaque propriété d’entité incluse dans le modèle de vue. Cette méthode fonctionne à la fois dans les scénarios de modification et de création.

    À part l’attribut Bind, le bloc try-catch est la seule modification que vous avez apportée au code généré. Si une exception qui dérive de DataException est interceptée lors de l’enregistrement des modifications, un message d’erreur générique est affiché. Les exceptions DataException sont parfois dues à quelque chose d’externe à l’application et non pas à une erreur de programmation : il est donc conseillé à l’utilisateur de réessayer. Bien que ceci ne soit pas implémenté dans cet exemple, une application destinée à la production doit consigner l’exception. Pour plus d’informations, consultez la section Log for insight dans Supervision et télémétrie (Création d’applications cloud réelles avec Azure).

    Le code dans Views\Student\Create.cshtml est similaire à ce que vous avez vu dans Details.cshtml, sauf que les helpers EditorFor et ValidationMessageFor sont utilisés pour chaque champ au lieu de DisplayFor. Voici le code correspondant :

    <div class="form-group">
        @Html.LabelFor(model => model.LastName, new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.LastName)
            @Html.ValidationMessageFor(model => model.LastName)
        </div>
    </div>
    

    Create.cshtml inclut également @Html.AntiForgeryToken(), qui fonctionne avec l’attribut ValidateAntiForgeryToken dans le contrôleur pour empêcher les attaques de falsification de requêtes intersites.

    Aucune modification n’est requise dans Create.cshtml.

  2. Ouvrez la page en démarrant le programme, en sélectionnant l’onglet Étudiants, puis en cliquant sur Créer.

  3. Entrez des noms et une date non valide, puis cliquez sur Créer pour afficher le message d’erreur.

    Il s’agit de la validation côté serveur que vous obtenez par défaut. Dans un didacticiel ultérieur, vous allez découvrir comment ajouter des attributs qui génèrent du code pour la validation côté client. Le code mis en surbrillance suivant montre la vérification de validation du modèle dans la méthode Create .

    if (ModelState.IsValid)
    {
        db.Students.Add(student);
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    
  4. Changez la date en une valeur valide, puis cliquez sur Créer pour voir apparaître le nouvel étudiant dans la page Index.

  5. Fermez le navigateur.

Mettre à jour la méthode HttpPost Edit

  1. Remplacez la méthode d’action HttpPostAttributeEdit par le code suivant :

    [HttpPost, ActionName("Edit")]
    [ValidateAntiForgeryToken]
    public ActionResult EditPost(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        var studentToUpdate = db.Students.Find(id);
        if (TryUpdateModel(studentToUpdate, "",
           new string[] { "LastName", "FirstMidName", "EnrollmentDate" }))
        {
            try
            {
                db.SaveChanges();
    
                return RedirectToAction("Index");
            }
            catch (DataException /* dex */)
            {
                //Log the error (uncomment dex variable name and add a line here to write a log.
                ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
            }
        }
        return View(studentToUpdate);
    }
    

    Remarque

    Dans Controllers\StudentController.cs, la HttpGet Edit méthode (celle sans l’attribut HttpPost ) utilise la Find méthode pour récupérer l’entité sélectionnée Student , comme vous l’avez vu dans la Details méthode. Vous n’avez pas besoin de modifier cette méthode.

    Ces modifications implémentent une bonne pratique de sécurité pour empêcher overposting, le générateur de code a généré un attribut Bind et ajouté l’entité créée par le lieur de modèles à l’ensemble d’entités avec un indicateur Modified. Ce code n’est plus recommandé, car l’attribut Bind efface toutes les données préexistantes dans les champs non répertoriés dans le Include paramètre. À l’avenir, le générateur de structure du contrôleur MVC sera mis à jour afin qu’il ne génère pas d’attributs Bind pour les méthodes Modifier.

    Le nouveau code lit l’entité existante et appelle TryUpdateModel pour mettre à jour les champs à partir de l’entrée utilisateur dans les données de formulaire publiées. Le suivi automatique des modifications d’Entity Framework définit l’indicateur EntityState.Modified sur l’entité. Lorsque la méthode SaveChanges est appelée, l’indicateur Modified provoque la création d’instructions SQL par Entity Framework pour mettre à jour la ligne de base de données. Les conflits d’accès concurrentiel sont ignorés et toutes les colonnes de la ligne de base de données sont mises à jour, y compris celles que l’utilisateur n’a pas changé. (Un didacticiel ultérieur montre comment gérer les conflits d’accès concurrentiel et si vous souhaitez uniquement que des champs individuels soient mis à jour dans la base de données, vous pouvez définir l’entité sur EntityState.Unchanged et définir des champs individuels sur EntityState.Modified.)

    Pour empêcher la survalidation, les champs dont vous voulez qu’ils puissent être mis à jour par la page Modifier sont listés dans les paramètres de TryUpdateModel. Actuellement, vous ne protégez aucun champ supplémentaire, mais le fait de répertorier les champs que vous voulez que le model binder lie garantit que si vous ajoutez ultérieurement des champs au modèle de données, ils seront automatiquement protégés jusqu’à ce que vous les ajoutiez explicitement ici.

    En raison de ces modifications, la signature de méthode de la méthode HttpPost Edit est la même que la méthode HttpGet edit ; vous avez donc renommé la méthode EditPost.

    Conseil

    États d’entité et méthodes Attach et SaveChanges

    Le contexte de base de données effectue le suivi de la synchronisation ou non des entités en mémoire avec leurs lignes correspondantes dans la base de données, et ces informations déterminent ce qui se passe quand vous appelez la méthode SaveChanges. Par exemple, lorsque vous transmettez une nouvelle entité à la méthode Add, l’état de cette entité est défini sur Added. Ensuite, lorsque vous appelez la méthode SaveChanges , le contexte de base de données émet une commande SQL INSERT .

    Une entité peut être dans l’un des états suivants :

    • Added. L’entité n’existe pas encore dans la base de données. La méthode SaveChanges doit émettre une instruction INSERT.
    • Unchanged. La méthode SaveChanges ne doit rien faire avec cette entité. Quand vous lisez une entité dans la base de données, l’entité a d’abord cet état.
    • Modified. Tout ou partie des valeurs de propriété de l’entité ont été modifiées. La méthode SaveChanges doit émettre une instruction UPDATE.
    • Deleted. L’entité a été marquée pour la suppression. La méthode SaveChanges doit émettre une instruction DELETE.
    • Detached. L’entité n’est pas suivie par le contexte de la base de données.

    Dans une application de bureau, les changements d’état sont généralement définis automatiquement. Dans un type d’application de bureau, vous lisez une entité et apportez des modifications à certaines de ses valeurs de propriété. Son état passe alors automatiquement à Modified. Ensuite, lorsque vous appelez SaveChanges, Entity Framework génère une instruction SQL UPDATE qui met à jour uniquement les propriétés réelles que vous avez modifiées.

    La nature déconnectée des applications web n’autorise pas cette séquence continue. DbContext qui lit une entité est supprimée après le rendu d’une page. Lorsque la HttpPostEdit méthode d’action est appelée, une nouvelle requête est effectuée et vous disposez d’une nouvelle instance de DbContext. Vous devez donc définir manuellement l’état de l’entité sur Modified.. Ensuite, lorsque vous appelez SaveChanges, Entity Framework met à jour toutes les colonnes de la ligne de base de données, car le contexte n’a aucun moyen de savoir quelles propriétés vous avez modifiées.

    Si vous souhaitez que l’instruction SQL Update mette à jour uniquement les champs que l’utilisateur a réellement modifiés, vous pouvez enregistrer les valeurs d’origine d’une certaine manière (comme les champs masqués) afin qu’elles soient disponibles lorsque la méthode HttpPostEdit est appelée. Vous pouvez ensuite créer une entité Student à l’aide des valeurs d’origine, appeler la méthode Attach avec cette version d’origine de l’entité, mettre à jour les valeurs de l’entité avec les nouvelles valeurs, puis appeler SaveChanges. Pour plus d’informations, consultez Les états d’entité et SaveChanges et Données locales.

    Le code HTML et Razor dans Views\Student\Edit.cshtml est similaire à ce que vous avez vu dans Create.cshtml et aucune modification n’est requise.

  2. Ouvrez la page en démarrant le programme, en sélectionnant l’onglet Étudiants, puis en cliquant sur l'hyperlien Modifier.

  3. Changez quelques données et cliquez sur Enregistrer. Vous voyez les données modifiées dans la page Index.

  4. Fermez le navigateur.

Mettre à jour la page Delete

Dans Controllers\StudentController.cs, le code de modèle de la HttpGetAttributeDelete méthode utilise la Find méthode pour récupérer l’entité Student sélectionnée, comme vous l’avez vu dans les méthodes Details et Edit. Cependant, pour implémenter un message d’erreur personnalisé quand l’appel à SaveChanges échoue, vous devez ajouter des fonctionnalités à cette méthode et à sa vue correspondante.

Comme vous l’avez vu pour les opérations de mise à jour et de création, les opérations de suppression nécessitent deux méthodes d’action. La méthode appelée en réponse à une requête GET affiche une vue qui permet à l’utilisateur d’approuver ou d’annuler l’opération de suppression. Si l’utilisateur l’approuve, une demande POST est créée. Lorsque cela se produit, la méthode HttpPostDelete est appelée, puis cette méthode effectue réellement l’opération de suppression.

Vous allez ajouter un try-catch bloc à la HttpPostAttributeDelete méthode pour gérer les erreurs qui peuvent se produire lorsque la base de données est mise à jour. Si une erreur se produit, la HttpPostAttributeDelete méthode appelle la HttpGetAttributeDelete méthode, en lui transmettant un paramètre qui indique qu’une erreur s’est produite. HttpGetAttribute Delete La méthode réaffiche ensuite la page de confirmation avec le message d’erreur, ce qui permet à l’utilisateur d’annuler ou de réessayer.

  1. Remplacez la méthode d’action HttpGetAttributeDelete par le code suivant, qui gère le rapport d’erreurs :

    public ActionResult Delete(int? id, bool? saveChangesError=false)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        if (saveChangesError.GetValueOrDefault())
        {
            ViewBag.ErrorMessage = "Delete failed. Try again, and if the problem persists see your system administrator.";
        }
        Student student = db.Students.Find(id);
        if (student == null)
        {
            return HttpNotFound();
        }
        return View(student);
    }
    

    Ce code accepte un paramètre facultatif qui indique si la méthode a été appelée après un échec d’enregistrement des modifications. Ce paramètre a la valeur false quand la méthode HttpGetDelete est appelée sans une erreur antérieure. Lorsqu’elle est appelée par la HttpPostDelete méthode en réponse à une erreur de mise à jour de base de données, le paramètre est true et un message d’erreur est transmis à la vue.

  2. Remplacez la HttpPostAttributeDelete méthode d’action (nommée DeleteConfirmed) par le code suivant, qui effectue l’opération de suppression réelle et intercepte les erreurs de mise à jour de base de données.

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Delete(int id)
    {
        try
        {
            Student student = db.Students.Find(id);
            db.Students.Remove(student);
            db.SaveChanges();
        }
        catch (DataException/* dex */)
        {
            //Log the error (uncomment dex variable name and add a line here to write a log.
            return RedirectToAction("Delete", new { id = id, saveChangesError = true });
        }
        return RedirectToAction("Index");
    }
    

    Ce code récupère l’entité sélectionnée, puis appelle la méthode Supprimer pour définir l’état de l’entité sur Deleted. Lorsque SaveChanges est appelé, une commande SQL DELETE est générée. Vous avez également changé le nom de la méthode d’action de DeleteConfirmed en Delete. Le code du modèle généré automatiquement utilisait la méthode HttpPostDeleteDeleteConfirmedpour donner à la méthode HttpPost une signature unique. ( Le CLR nécessite des méthodes surchargées pour avoir des paramètres de méthode différents.) Maintenant que les signatures sont uniques, vous pouvez respecter la convention MVC et utiliser le même nom pour les méthodes de suppression HttpPost et HttpGet.

    Si l’amélioration des performances dans une application à volume élevé est une priorité, vous pouvez éviter une requête SQL inutile pour récupérer la ligne en remplaçant les lignes de code qui appellent les méthodes Find et Remove par le code suivant :

    Student studentToDelete = new Student() { ID = id };
    db.Entry(studentToDelete).State = EntityState.Deleted;
    

    Ce code instancie une entité Student en utilisant uniquement la valeur de clé primaire, puis définit ensuite l’état de l’entité sur Deleted. C’est tout ce dont a besoin Entity Framework pour pouvoir supprimer l’entité.

    Comme indiqué, la HttpGetDelete méthode ne supprime pas les données. L’exécution d’une opération de suppression en réponse à une requête GET (ou à ce titre, l’exécution d’une opération de modification, l’opération de création ou toute autre opération qui modifie les données) crée un risque de sécurité.

  3. Dans Views\Student\Delete.cshtml, ajoutez un message d’erreur entre le h2 titre et le h3 titre, comme illustré dans l’exemple suivant :

    <h2>Delete</h2>
    <p class="error">@ViewBag.ErrorMessage</p>
    <h3>Are you sure you want to delete this?</h3>
    
  4. Ouvrez la page en démarrant le programme, en sélectionnant l’onglet Étudiants, puis en cliquant sur l'hyperlien Supprimer.

  5. Choisissez Supprimer sur la page qui indique Êtes-vous sûr de vouloir le supprimer ?.

    La page Index s’affiche sans l’étudiant supprimé. (Vous verrez un exemple de code de gestion des erreurs en action dans le didacticiel sur la concurrence.)

Fermer les connexions de base de données

Pour fermer les connexions à la base de données et libérer au plus vite les ressources qu'elles occupent, fermez l'instance de contexte dès que vous n'en avez plus besoin. C’est pourquoi le code généré automatiquement fournit une méthode Dispose à la fin de la StudentController classe dans StudentController.cs, comme illustré dans l’exemple suivant :

protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        db.Dispose();
    }
    base.Dispose(disposing);
}

La classe de base Controller implémente déjà l’interface IDisposable. Ce code ajoute simplement une redéfinition de la méthode Dispose(bool) pour libérer explicitement l’instance de contexte.

Gérer les transactions

Par défaut, Entity Framework implémente implicitement les transactions. Dans les scénarios où vous apportez des modifications à plusieurs lignes ou plusieurs tables, puis que appelez SaveChanges, Entity Framework garantit automatiquement que soit toutes vos modifications réussissent soit elles échouent toutes. Si certaines modifications sont effectuées en premier puis qu’une erreur se produit, ces modifications sont automatiquement annulées. Pour les scénarios où vous avez besoin d’un contrôle supplémentaire( par exemple, si vous souhaitez inclure des opérations effectuées en dehors d’Entity Framework dans une transaction), consultez Utilisation des transactions.

Ressources supplémentaires

Vous avez maintenant un ensemble complet de pages qui effectuent des opérations CRUD simples pour les entités Student. Vous avez utilisé des helpers MVC pour générer des éléments d’interface utilisateur pour les champs de données. Pour plus d’informations sur les helpers MVC, consultez Rendu d’un formulaire à l’aide de l’aide HTML (l’article concerne MVC 3, mais il est toujours pertinent pour MVC 5).

Vous trouverez des liens vers d’autres ressources EF 6 dans ASP.NET Accès aux données - Ressources recommandées.

Étapes suivantes

Dans ce tutoriel, vous allez :

  • Création d'une page Détails
  • Mettre à jour la page Create
  • Méthode HttpPost Edit mise à jour
  • Mettre à jour la page Delete
  • Connexions de base de données fermées
  • Transactions gérées

Passez à l’article suivant pour apprendre à ajouter le tri, le filtrage et la pagination au projet.