Freigeben über


Lernprogramm: Implementieren der CRUD-Funktionalität mit dem Entity Framework in ASP.NET MVC

Im vorherigen Lernprogramm haben Sie eine MVC-Anwendung erstellt, die Daten mithilfe von Entity Framework (EF) 6 und SQL Server LocalDB speichert und anzeigt. In diesem Lernprogramm überprüfen und anpassen Sie den Code zum Erstellen, Lesen, Aktualisieren, Löschen (CRUD), den das MVC-Gerüst automatisch für Sie in Controllern und Ansichten erstellt.

Hinweis

Es ist üblich, dass das Repositorymuster implementiert wird, um eine Abstraktionsebene zwischen Ihrem Controller und der Datenzugriffsebene zu erstellen. Um diese Lernprogramme einfach zu halten und sich auf die Verwendung von EF 6 selbst zu konzentrieren, verwenden sie keine Repositorys. Informationen zum Implementieren von Repositorys finden Sie in der ASP.NET Inhaltszuordnung für den Datenzugriff.

Hier sind Beispiele für die webseiten, die Sie erstellen:

Screenshot der Seite

Screenshot der Seite

Screenshot der Seite zum Löschen des Kursteilnehmers.

In diesem Tutorial:

  • Erstellen einer Detailseite
  • Aktualisieren der Seite „Erstellen“
  • Aktualisieren der HttpPost Edit-Methode
  • Aktualisieren der Seite „Delete“ (Löschen)
  • Schließen von Datenbankverbindungen
  • Behandeln von Transaktionen

Voraussetzungen

Erstellen einer Detailseite

Der Gerüstcode für die Seite "Kursteilnehmer Index " hat die Enrollments Eigenschaft ausgelassen, da diese Eigenschaft eine Auflistung enthält. Auf der Details Seite zeigen Sie den Inhalt der Auflistung in einer HTML-Tabelle an.

In Controllers\StudentController.cs verwendet die Aktionsmethode für die Details Ansicht die Find-Methode , um eine einzelne Student Entität abzurufen.

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);
}

Der Schlüsselwert wird als id Parameter an die Methode übergeben und stammt aus Routendaten im Link "Details " auf der Indexseite.

Tipp: Routen von Daten

Routingdaten sind Daten, die der Modellordner in einem URL-Segment gefunden hat, das in der Routingtabelle angegeben ist. Die Standardroute gibt z. B. , actionund id Segmente ancontroller:

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

In der folgenden URL wird Instructor die Standardroute als die controllerund Index 1 als die action id; dies sind Routendatenwerte.

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

?courseID=2021 ist ein Abfragezeichenfolgenwert. Der Modellordner funktioniert auch, wenn Sie den id Abfragezeichenfolgenwert übergeben:

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

Die URLs werden von ActionLink Anweisungen in der Razor-Ansicht erstellt. Im folgenden Code entspricht der id Parameter der Standardroute, wird also id den Routendaten hinzugefügt.

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

Im folgenden Code courseID stimmt er nicht mit einem Parameter in der Standardroute überein, daher wird er als Abfragezeichenfolge hinzugefügt.

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

So erstellen Sie die Seite "Details"

  1. Öffnen Sie "Views\Student\Details.cshtml".

    Jedes Feld wird mithilfe eines DisplayFor Hilfsfelds angezeigt, wie im folgenden Beispiel gezeigt:

    <dt>
        @Html.DisplayNameFor(model => model.LastName)
    </dt>
    <dd>
        @Html.DisplayFor(model => model.LastName)
    </dd>
    
  2. Fügen Sie nach dem EnrollmentDate Feld und unmittelbar vor dem schließenden </dl> Tag den hervorgehobenen Code hinzu, um eine Liste der Registrierungen anzuzeigen, wie im folgenden Beispiel gezeigt:

    <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>
    

    Wenn der Codeeinzug nach dem Einfügen des Codes falsch ist, drücken Sie STRG+K, STRG+D , um ihn zu formatieren.

    Dieser Code durchläuft die Entitäten in der Navigationseigenschaft Enrollments. Für jede Enrollment Entität in der Eigenschaft werden der Kurstitel und die Noten angezeigt. Der Kurstitel wird von der Course Entität abgerufen, die in der Course Navigationseigenschaft der Enrollments Entität gespeichert ist. Alle diese Daten werden automatisch aus der Datenbank abgerufen, wenn sie benötigt werden. Mit anderen Worten, Sie verwenden faules Laden hier. Sie haben kein begieriges Laden für die Courses Navigationseigenschaft angegeben, sodass die Registrierungen nicht in derselben Abfrage abgerufen wurden, die die Kursteilnehmer erhalten hat. Stattdessen wird beim ersten Versuch, auf die Enrollments Navigationseigenschaft zuzugreifen, eine neue Abfrage an die Datenbank gesendet, um die Daten abzurufen. Weitere Informationen zum faulen Laden und eifrigen Laden finden Sie im Lernprogramm "Lesen verwandter Daten " weiter unten in dieser Reihe.

  3. Öffnen Sie die Seite "Details", indem Sie das Programm (STRG+F5) starten, die Registerkarte "Kursteilnehmer " auswählen und dann auf den Link "Details " für Alexander Carson klicken. (Wenn Sie STRG+F5, während die Datei "Details.cshtml" geöffnet ist, wird ein HTTP 400-Fehler angezeigt. Dies liegt daran, dass Visual Studio versucht, die Seite "Details" auszuführen, aber nicht über einen Link erreicht wurde, der den anzuzeigenden Kursteilnehmer angibt. Entfernen Sie in diesem Fall "Schüler/Details" aus der URL, und versuchen Sie es erneut, oder schließen Sie den Browser, klicken Sie mit der rechten Maustaste auf das Projekt, und klicken Sie dann im Browser auf "Ansicht anzeigen>".)

    Die Liste der Kurse und Noten für den ausgewählten Kursteilnehmer wird angezeigt.

  4. Schließen Sie den Browser.

Aktualisieren der Seite „Erstellen“

  1. Ersetzen Sie in Controller\StudentController.cs die HttpPostAttribute Create Aktionsmethode durch den folgenden Code. Dieser Code fügt einen try-catch Block hinzu und entfernt ID aus dem BindAttribute Attribut für die Gerüstmethode:

    [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);
    }
    

    Dieser Code fügt die Student entität, die vom ASP.NET MVC-Modellbinder erstellt wurde, zum Students Entitätssatz hinzu und speichert dann die Änderungen in der Datenbank. Modellbinder bezieht sich auf die ASP.NET MVC-Funktionalität, die es Ihnen erleichtert, mit daten zu arbeiten, die von einem Formular übermittelt werden. Ein Modellordner konvertiert gepostete Formularwerte in CLR-Typen und übergibt sie an die Aktionsmethode in Parameter. In diesem Fall instanziiert der Modellbinder eine Student Entität für Sie mithilfe von Eigenschaftswerten aus der Form Auflistung.

    Sie haben das Bind-Attribut entfernt ID , da ID es sich um den Primärschlüsselwert handelt, den SQL Server beim Einfügen der Zeile automatisch festlegt. Die Eingabe des Benutzers legt den ID Wert nicht fest.

    Sicherheitswarnung – Das ValidateAntiForgeryToken Attribut verhindert websiteübergreifende Fälschungsangriffe . Sie erfordert eine entsprechende Html.AntiForgeryToken() Anweisung in der Ansicht, die Sie später sehen werden.

    Das Bind Attribut ist eine Möglichkeit, um vor Überbuchungen in Erstellungsszenarien zu schützen. Angenommen, die Student Entität enthält eine Secret Eigenschaft, die von dieser Webseite nicht festgelegt werden soll.

    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; }
    }
    

    Auch wenn Sie kein Feld auf der Webseite haben Secret , könnte ein Hacker ein Tool wie Fiddler verwenden oder javaScript schreiben, um einen Secret Formularwert zu veröffentlichen. Ohne das BindAttribute Attribut, das die Felder beschränkt, die der Modellordner beim Erstellen einer Student Instanz verwendet, würde der Modellordner diesen Secret Formularwert aufnehmen und zum Erstellen der Entitätsinstanz Student verwenden. Dann würde jeder beliebige Wert in Ihre Datenbank aktualisiert werden, den der Hacker für das Formularfeld Secret festlegt. Die folgende Abbildung zeigt das Fiddler-Tool, das das Secret Feld (mit dem Wert "OverPost") zu den geposteten Formularwerten hinzufügt.

    Screenshot der Registerkarte

    Der Wert „OverPost“ würde dann erfolgreich der Eigenschaft Secret der eingefügten Zeile hinzugefügt werden, obwohl Sie nie beabsichtigt haben, dass die Webseite diese Eigenschaft festlegen kann.

    Es ist am besten, den Include Parameter mit dem Bind Attribut zum expliziten Auflisten von Feldern zu verwenden. Es ist auch möglich, den Parameter zum Blockieren von Exclude Feldern zu verwenden, die Sie ausschließen möchten. Der Grund Include dafür ist, dass das neue Feld nicht automatisch durch eine Exclude Liste geschützt wird, wenn Sie der Entität eine neue Eigenschaft hinzufügen.

    Sie können das Überposten in Bearbeitungsszenarien verhindern, indem Sie zuerst die Entität aus der Datenbank lesen und dann eine explizite Liste zulässiger Eigenschaften übergeben TryUpdateModel. Dies ist die Methode, die in diesen Lernprogrammen verwendet wird.

    Eine alternative Möglichkeit zum Verhindern von Überpostungen, die von vielen Entwicklern bevorzugt werden, besteht darin, Ansichtsmodelle anstelle von Entitätsklassen mit Modellbindung zu verwenden. Schließen Sie nur die Eigenschaften in dem Ansichtsmodell ein, die Sie aktualisieren möchten. Nachdem der MVC-Modellordner abgeschlossen ist, kopieren Sie die Ansichtsmodelleigenschaften in die Entitätsinstanz, optional mithilfe eines Tools wie AutoMapper. Verwenden Sie db. Eintrag in der Entitätsinstanz, um den Status auf "Unverändert" festzulegen, und legen Sie dann Property("PropertyName") fest. IsModified to true on each entity property that is included in the view model. Diese Methode funktioniert sowohl im Bearbeitungsszenario als auch im Erstellungsszenario.

    Abgesehen vom Bind Attribut ist der try-catch Block die einzige Änderung, die Sie am Gerüstcode vorgenommen haben. Wenn eine Ausnahme abgefangen wird, die von DataException abgeleitet wird, während die Änderungen gespeichert werden, wird eine generische Fehlermeldung angezeigt. DataException-Ausnahmen werden manchmal durch etwas außerhalb der Anwendung ausgelöst, und nicht durch einen Programmierfehler. Es wird empfohlen, dass der Benutzer es erneut versucht. Zwar wird es in diesem Beispiel nicht implementiert, aber eine qualitätsorientierte Produktionsanwendung würde die Ausnahme protokollieren. Weitere Informationen finden Sie im Abschnitt Log for insight (Einblicke durch Protokollierung) im Artikel Monitoring and Telemetry (Building Real-World Cloud Apps with Azure) (Überwachung und Telemetrie (Erstellen von realitätsnahen Cloud-Apps mit Azure)).

    Der Code in Views\Student\Create.cshtml ähnelt dem, was Sie in Details.cshtml gesehen haben, außer dass EditorFor und ValidationMessageFor Hilfsprogramme für jedes Feld anstelle von DisplayFor. Hier ist der entsprechende Code:

    <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 enthält @Html.AntiForgeryToken()auch , das mit dem ValidateAntiForgeryToken Attribut im Controller funktioniert, um websiteübergreifende Anforderungsverfälschungsangriffe zu verhindern.

    In Create.cshtml sind keine Änderungen erforderlich.

  2. Führen Sie die Seite aus, indem Sie das Programm starten, die Registerkarte "Kursteilnehmer" auswählen und dann auf "Neu erstellen" klicken.

  3. Geben Sie Namen und ein ungültiges Datum ein, und klicken Sie auf " Erstellen ", um die Fehlermeldung anzuzeigen.

    Dies ist die serverseitige Überprüfung, die Sie standardmäßig erhalten. In einem späteren Lernprogramm erfahren Sie, wie Sie Attribute hinzufügen, die Code für die clientseitige Überprüfung generieren. Der folgende hervorgehobene Code zeigt die Modellüberprüfung in der Create-Methode .

    if (ModelState.IsValid)
    {
        db.Students.Add(student);
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    
  4. Ändern Sie das Datum in einen gültigen Wert und klicken auf Erstellen, damit der neue Student auf der Seite Index angezeigt wird.

  5. Schließen Sie den Browser.

Update HttpPost Edit-Methode

  1. Ersetzen Sie die HttpPostAttribute Edit Aktionsmethode durch den folgenden Code:

    [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);
    }
    

    Hinweis

    In Controllers\StudentController.cs verwendet die HttpGet Edit Methode (die methode ohne das HttpPost Attribut) die Find Methode, um die ausgewählte Student Entität abzurufen, wie Sie in der Details Methode gesehen haben. Sie müssen diese Methode nicht ändern.

    Diese Änderungen implementieren eine bewährte Methode zur Sicherheit, um die Überpostung zu verhindern, das Gerüst hat ein Bind Attribut generiert und die vom Modellordner erstellte Entität zur Entität hinzugefügt, die mit einem Geänderten Flag festgelegt wurde. Dieser Code wird nicht mehr empfohlen, da das Bind Attribut bereits vorhandene Daten in Feldern löscht, die Include nicht im Parameter aufgeführt sind. In Zukunft wird das MVC-Controllergerüst aktualisiert, sodass es keine Attribute für Edit-Methoden generiert Bind .

    Der neue Code liest die vorhandene Entität und Aufrufe TryUpdateModel zum Aktualisieren von Feldern von Benutzereingaben in den bereitgestellten Formulardaten. Die automatische Änderungsnachverfolgung von Entity Framework legt das Flag "EntityState.Modified " für die Entität fest. Wenn die SaveChanges-Methode aufgerufen wird, bewirkt das Modified Flag, dass das Entity Framework SQL-Anweisungen erstellt, um die Datenbankzeile zu aktualisieren. Parallelitätskonflikte werden ignoriert, und alle Spalten der Datenbankzeile werden aktualisiert, einschließlich derJenigen, die der Benutzer nicht geändert hat. (In einem späteren Lernprogramm wird gezeigt, wie Parallelitätskonflikte behandelt werden. Wenn nur einzelne Felder in der Datenbank aktualisiert werden sollen, können Sie die Entität aufEntityState.Unchanged and set individual fields to EntityState.Modified.)

    Um das Überposten zu verhindern, werden die Felder, die von der Seite "Bearbeiten" aktualisiert werden sollen, in den TryUpdateModel Parametern aufgeführt. Derzeit sind keine zusätzlichen von Ihnen geschützten Felder vorhanden. Wenn Sie jedoch die Felder auflisten, die die Modellbindung binden soll, stellen Sie sicher, dass zukünftig hinzugefügte Felder automatisch geschützt sind, bis Sie sie explizit hier hinzufügen.

    Aufgrund dieser Änderungen ist die Methodensignatur der HttpPost Edit-Methode identisch mit der HttpGet-Bearbeitungsmethode; daher haben Sie die Methode EditPost umbenannt.

    Tipp

    Entitätszustände und die Methoden "Attach" und "SaveChanges"

    Der Datenbankkontext verfolgt, ob die Entitäten im Arbeitsspeicher mit ihren entsprechenden Zeilen in der Datenbank synchronisiert sind. Diese Information bestimmt, was passiert, wenn Sie die Methode SaveChanges aufrufen. Wenn Sie beispielsweise eine neue Entität an die Add-Methode übergeben, wird der Status dieser Entität auf " Added. Wenn Sie dann die SaveChanges-Methode aufrufen, gibt der Datenbankkontext einen SQL-Befehl INSERT aus.

    Eine Entität kann einen der folgenden Status aufweisen:

    • Added. Die Entität ist in der Datenbank noch nicht vorhanden. Die SaveChanges Methode muss eine INSERT Anweisung ausgeben.
    • Unchanged. Die Methode SaveChanges muss nichts mit dieser Entität tun. Wenn Sie eine Entität aus der Datenbank lesen, beginnt die Entität mit diesem Status.
    • Modified. Einige oder alle Eigenschaftswerte der Entität wurden geändert. Die SaveChanges Methode muss eine UPDATE Anweisung ausgeben.
    • Deleted. Die Entität wurde zum Löschen markiert. Die SaveChanges Methode muss eine DELETE Anweisung ausgeben.
    • Detached. Die Entität wird nicht vom Datenbankkontext nachverfolgt.

    Statusänderungen werden in einer Desktop-App in der Regel automatisch festgelegt. In einem Desktoptyp der Anwendung lesen Sie eine Entität und nehmen Änderungen an einigen seiner Eigenschaftswerte vor. Dadurch wird der Entitätsstatus automatisch auf Modified festgelegt. Wenn Sie dann aufrufen SaveChanges, generiert Das Entity Framework eine SQL-Anweisung UPDATE , die nur die tatsächlichen Eigenschaften aktualisiert, die Sie geändert haben.

    Die getrennte Art von Web-Apps lässt diese fortlaufende Sequenz nicht zu. Der DbContext , der eine Entität liest, wird gelöscht, nachdem eine Seite gerendert wurde. Wenn die HttpPost Edit Aktionsmethode aufgerufen wird, wird eine neue Anforderung gestellt, und Sie haben eine neue Instanz des DbContext, sodass Sie den Entitätsstatus Modified. manuell auf "Then" festlegen müssen, wenn Sie aufrufen SaveChanges, aktualisiert das Entity Framework alle Spalten der Datenbankzeile, da der Kontext keine Möglichkeit hat, zu wissen, welche Eigenschaften Sie geändert haben.

    Wenn die SQL-Anweisung Update nur die Felder aktualisieren soll, die der Benutzer tatsächlich geändert hat, können Sie die ursprünglichen Werte auf irgendeine Weise (z. B. ausgeblendete Felder) speichern, sodass sie beim Aufrufen der HttpPost Edit Methode verfügbar sind. Anschließend können Sie eine Student Entität mit den ursprünglichen Werten erstellen, die Methode mit dieser Attach ursprünglichen Version der Entität aufrufen, die Werte der Entität auf die neuen Werte aktualisieren und dann SaveChanges. weitere Informationen aufrufen, siehe Entitätszustände und SaveChanges und lokale Daten.

    Der HTML- und Razor-Code in Views\Student\Edit.cshtml ähnelt dem, was Sie in Create.cshtml gesehen haben, und es sind keine Änderungen erforderlich.

  2. Führen Sie die Seite aus, indem Sie das Programm starten, die Registerkarte "Kursteilnehmer " auswählen und dann auf einen Link "Bearbeiten " klicken.

  3. Ändern Sie einige der Daten, und klicken Sie auf Speichern. Die geänderten Daten werden auf der Indexseite angezeigt.

  4. Schließen Sie den Browser.

Aktualisieren der Seite „Delete“ (Löschen)

In Controllers\StudentController.cs verwendet der Vorlagencode für die HttpGetAttribute Delete Methode die Find Methode, um die ausgewählte Student Entität abzurufen, wie Sie in den Details und Edit den Methoden gesehen haben. Allerdings müssen Sie dieser Methode und der dazugehörigen Ansicht einige Funktionen hinzufügen, um eine benutzerdefinierte Fehlermeldung zu implementieren, wenn der Aufruf von SaveChanges fehlschlägt.

Wie Sie bereits bei den Vorgängen zum Aktualisieren und Erstellen gesehen haben, benötigen Löschvorgänge zwei Aktionsmethoden. Die Methode, die als Reaktion auf eine GET-Anforderung aufgerufen wird, zeigt eine Ansicht an, die dem Benutzer die Möglichkeit gibt, den Löschvorgang zu genehmigen oder abzubrechen. Wenn der Benutzer diesen Löschvorgang genehmigt, wird eine POST-Anforderung erstellt. In diesem Fall wird die HttpPost Delete Methode aufgerufen, und dann führt diese Methode tatsächlich den Löschvorgang aus.

Sie fügen der HttpPostAttribute Delete Methode einen try-catch Block hinzu, um alle Fehler zu behandeln, die auftreten können, wenn die Datenbank aktualisiert wird. Wenn ein Fehler auftritt, ruft die HttpPostAttribute Delete Methode die HttpGetAttribute Delete Methode auf und übergibt einen Parameter, der angibt, dass ein Fehler aufgetreten ist. Die HttpGetAttribute Delete Methode zeigt dann die Bestätigungsseite zusammen mit der Fehlermeldung erneut an, sodass der Benutzer die Möglichkeit erhält, den Vorgang abzubrechen oder erneut zu versuchen.

  1. Ersetzen Sie die HttpGetAttribute Delete Aktionsmethode durch den folgenden Code, der die Fehlerberichterstattung verwaltet:

    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);
    }
    

    Dieser Code akzeptiert einen optionalen Parameter , der angibt, ob die Methode nach einem Fehler beim Speichern von Änderungen aufgerufen wurde. Dieser Parameter wird false aufgerufen, wenn die HttpGet Delete Methode ohne vorherigen Fehler aufgerufen wird. Wenn sie von der HttpPost Delete Methode als Reaktion auf einen Datenbankaktualisierungsfehler aufgerufen wird, wird true der Parameter und eine Fehlermeldung an die Ansicht übergeben.

  2. Ersetzen Sie die HttpPostAttribute Delete Aktionsmethode (benannt DeleteConfirmed) durch den folgenden Code, der den tatsächlichen Löschvorgang ausführt, und erfasst alle Datenbankaktualisierungsfehler.

    [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");
    }
    

    Dieser Code ruft die ausgewählte Entität ab und ruft dann die Remove-Methode auf, um den Status der Entität auf festzulegen Deleted. Beim Aufruf von SaveChanges wird der SQL-Befehl DELETE generiert. Ebenfalls haben Sie den Namen der Aktionsmethode DeleteConfirmed auf Delete geändert. Der Gerüstcode namens der HttpPost Delete Methode, um der HttpPost Methode DeleteConfirmed eine eindeutige Signatur zu geben. (Die CLR erfordert überladene Methoden, um unterschiedliche Methodenparameter zu haben.) Nachdem die Signaturen eindeutig sind, können Sie mit der MVC-Konvention bleiben und denselben Namen für die HttpPost Methoden und HttpGet Löschmethoden verwenden.

    Wenn es sich bei der Verbesserung der Leistung in einer Anwendung mit hohem Volumen um eine Priorität handelt, können Sie eine unnötige SQL-Abfrage vermeiden, um die Zeile abzurufen, indem Sie die Codezeilen ersetzen, die die Find Und Remove Methoden durch den folgenden Code aufrufen:

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

    Dieser Code instanziiert eine Student Entität nur mit dem Primärschlüsselwert und legt dann den Entitätsstatus auf Deleted. Das ist alles, was Entity Framework benötigt, um die Entität löschen zu können.

    Wie bereits erwähnt, löscht die HttpGet Delete Methode die Daten nicht. Das Ausführen eines Löschvorgangs als Reaktion auf eine GET-Anforderung (oder für diese Frage, das Ausführen eines Bearbeitungsvorgangs, eines Erstellungsvorgangs oder eines anderen Vorgangs, der Daten ändert) führt zu einem Sicherheitsrisiko.

  3. Fügen Sie in Views\Student\Delete.cshtml eine Fehlermeldung zwischen der h2 Überschrift und der h3 Überschrift hinzu, wie im folgenden Beispiel gezeigt:

    <h2>Delete</h2>
    <p class="error">@ViewBag.ErrorMessage</p>
    <h3>Are you sure you want to delete this?</h3>
    
  4. Führen Sie die Seite aus, indem Sie das Programm starten, die Registerkarte "Kursteilnehmer " auswählen und dann auf einen Link löschen klicken.

  5. Wählen Sie "Löschen" auf der Seite mit der Meldung "Möchten Sie dies wirklich löschen?".

    Die Indexseite wird ohne den gelöschten Kursteilnehmer angezeigt. (Im Parallelitätslernprogramm sehen Sie ein Beispiel für den Fehlerbehandlungscode in Aktion.)

Schließen von Datenbankverbindungen

Um Datenbankverbindungen zu schließen und die ressourcen freizugeben, die sie so schnell wie möglich enthalten, löschen Sie die Kontextinstanz, wenn Sie damit fertig sind. Aus diesem Grund stellt der Gerüstcode am Ende der StudentController Klasse in StudentController.cs eine Dispose-Methode bereit, wie im folgenden Beispiel gezeigt:

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

Die Basisklasse Controller implementiert bereits die IDisposable Schnittstelle, sodass dieser Code der Methode einfach eine Außerkraftsetzung Dispose(bool) hinzufügt, um die Kontextinstanz explizit zu löschen.

Behandeln von Transaktionen

Standardgemäß implementiert Entity Framework implizit Transaktionen. In Szenarien, in denen Sie Änderungen an mehreren Zeilen oder Tabellen vornehmen und dann aufrufen SaveChanges, stellt das Entity Framework automatisch sicher, dass alle Ihre Änderungen erfolgreich sind oder alle fehlschlagen. Wenn ein Fehler auftritt, nachdem einige der Änderungen durchgeführt wurden, werden diese Änderungen automatisch zurückgesetzt. Szenarien, in denen Sie mehr Kontrolle benötigen , z. B. wenn Sie Vorgänge außerhalb von Entity Framework in eine Transaktion einbeziehen möchten, finden Sie unter Arbeiten mit Transaktionen.

Abrufen des Codes

Abgeschlossenes Projekt herunterladen

Zusätzliche Ressourcen

Sie verfügen jetzt über einen vollständigen Satz von Seiten, die einfache CRUD-Vorgänge für Student Entitäten ausführen. Sie haben MVC-Hilfsprogramme verwendet, um UI-Elemente für Datenfelder zu generieren. Weitere Informationen zu MVC-Hilfsern finden Sie unter Rendern eines Formulars mithilfe von HTML-Hilfselementen (der Artikel gilt für MVC 3, ist aber weiterhin für MVC 5 relevant).

Links zu anderen EF 6-Ressourcen finden Sie in ASP.NET Datenzugriff – Empfohlene Ressourcen.

Nächste Schritte

In diesem Tutorial haben Sie:

  • Seite "Details" erstellt
  • Die Seite „Erstellen“ aktualisiert
  • Die HttpPost Edit-Methode wurde aktualisiert.
  • Die Seite „Löschen“ aktualisiert
  • Datenbankverbindungen geschlossen
  • Verarbeitete Transaktionen

Wechseln Sie zum nächsten Artikel, um zu erfahren, wie Sie dem Projekt Sortier-, Filter- und Auslagerungen hinzufügen.