Tutorial: Implementieren der CRUD-Funktionalität mit dem Entity Framework in ASP.NET MVC
Im vorherigen Tutorial haben Sie eine MVC-Anwendung erstellt, die Daten mithilfe von Entity Framework (EF) 6 und SQL Server LocalDB speichert und anzeigt. In diesem Tutorial überprüfen und anpassen Sie den CRUD-Code (Erstellen, Lesen, Aktualisieren, Löschen), 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 Tutorials 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 unter ASP.NET Data Access Content Map.
Hier finden Sie Beispiele für die von Ihnen erstellten Webseiten:
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 Schüler Index
hat die Enrollments
Eigenschaft weggelassen, 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 Seite Index.
Tipp: Routendaten
Routingdaten sind Daten, die der Modellbinder in einem URL-Segment gefunden hat, das in der Routingtabelle angegeben ist. Die Standardroute gibt beispielsweise , action
und 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 die Standardroute als controller
, als das action
und 1 als der id
zugeordnet. Dabei handelt es sich Instructor
um Index
Routendatenwerte.
http://localhost:1230/Instructor/Index/1?courseID=2021
?courseID=2021
ist ein Abfragezeichenfolgenwert. Der Modellbinder funktioniert auch, wenn Sie den id
als 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 stimmt der id
Parameter mit der Standardroute überein, sodass id
den Routendaten hinzugefügt wird.
@Html.ActionLink("Select", "Index", new { id = item.PersonID })
Stimmt im folgenden Code courseID
nicht mit einem Parameter in der Standardroute überein, sodass er als Abfragezeichenfolge hinzugefügt wird.
@Html.ActionLink("Select", "Index", new { courseID = item.CourseID })
So erstellen Sie die Seite "Details"
Öffnen Sie Views\Student\Details.cshtml.
Jedes Feld wird mit einem
DisplayFor
Hilfsprogramm angezeigt, wie im folgenden Beispiel gezeigt:<dt> @Html.DisplayNameFor(model => model.LastName) </dt> <dd> @Html.DisplayFor(model => model.LastName) </dd>
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 jedeEnrollment
Entität in der Eigenschaft werden der Kurstitel und die Note angezeigt. Der Kurstitel wird von derCourse
Entität abgerufen, die in derCourse
Navigationseigenschaft derEnrollments
Entität gespeichert ist. Alle diese Daten werden automatisch aus der Datenbank abgerufen, wenn sie benötigt werden. Mit anderen Worten, Sie verwenden hier das verzögerte Laden. Sie haben keine Eiferladung für dieCourses
Navigationseigenschaft angegeben, sodass die Registrierungen nicht in derselben Abfrage abgerufen wurden, die die Kursteilnehmer erhalten hat. Stattdessen wird beim ersten Versuch, auf dieEnrollments
Navigationseigenschaft zuzugreifen, eine neue Abfrage an die Datenbank gesendet, um die Daten abzurufen. Weitere Informationen zu verzögertem Laden und eifrigem Laden finden Sie im Tutorial Lesen verwandter Daten weiter unten in dieser Reihe.Öffnen Sie die Seite Details, indem Sie das Programm starten (STRG+F5), die Registerkarte Schüler auswählen und dann auf den Link Details für Alexander Carson klicken. (Wenn Sie STRG+ drückenF5, während die Datei Details.cshtml geöffnet ist, erhalten Sie einen HTTP 400-Fehler. Dies liegt daran, dass Visual Studio versucht, die Detailseite auszuführen, aber nicht über einen Link erreicht wurde, der den anzuzeigenden Kursteilnehmer angibt. Entfernen Sie in diesem Fall "Student/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 aufIm Browser anzeigen>.)
Die Liste der Kurse und Noten für den ausgewählten Kursteilnehmer wird angezeigt.
Schließen Sie den Browser.
Aktualisieren der Seite „Erstellen“
Ersetzen Sie in Controller\StudentController.cs die HttpPostAttribute
Create
Aktionsmethode durch den folgenden Code. Dieser Code fügt einentry-catch
Block hinzu und entferntID
aus dem BindAttribute Attribut für die gerüstete Methode:[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 der Entität hinzu, die
Student
vom ASP.NET MVC-Modellbinder erstellt wurde, demStudents
Entitätssatz und speichert dann die Änderungen in der Datenbank. Modellbinder bezieht sich auf die ASP.NET MVC-Funktionalität, die Ihnen das Arbeiten mit Daten erleichtert, die von einem Formular übermittelt werden. ein Modellbinder konvertiert gebuchte Formularwerte in CLR-Typen und übergibt sie in Parametern an die Aktionsmethode. In diesem Fall instanziiert der Modellbinder eineStudent
Entität für Sie mithilfe von Eigenschaftswerten aus derForm
Auflistung.Sie haben
ID
das Bind-Attribut entfernt, da es sich umID
den Primärschlüsselwert handelt, der SQL Server automatisch festlegt, wenn die Zeile eingefügt wird. Die Eingabe des Benutzers legt denID
Wert nicht fest.Sicherheitswarnung: Das
ValidateAntiForgeryToken
Attribut hilft dabei, siteübergreifende Anforderungsfälschungsangriffe zu verhindern. Es erfordert eine entsprechendeHtml.AntiForgeryToken()
Anweisung in der Ansicht, die Später angezeigt wird.Das
Bind
Attribut ist eine Möglichkeit, um in Erstellungsszenarien vor Überbuchungen zu schützen. Angenommen, dieStudent
Entität enthält eineSecret
Eigenschaft, die diese Webseite nicht festlegen 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; } }
Selbst wenn Sie kein Feld auf der Webseite haben
Secret
, kann ein Hacker ein Tool wie Fiddler verwenden oder javaScript schreiben, um einenSecret
Formularwert zu posten. Ohne das BindAttribute Attribut, das die Felder einschränkt, die der Modellbinder beim Erstellen einerStudent
instance verwendet, würde der Modellbinder diesenSecret
Formularwert aufgreifen und zum Erstellen derStudent
Entität instance verwenden. Dann würde jeder beliebige Wert in Ihre Datenbank aktualisiert werden, den der Hacker für das FormularfeldSecret
festlegt. Die folgende Abbildung zeigt das Fiddler-Tool, das dasSecret
Feld (mit dem Wert "OverPost") zu den gebuchten Formularwerten hinzufügt.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 demBind
-Attribut zu verwenden, um Felder explizit aufzulisten. Es ist auch möglich, denExclude
Parameter zu verwenden, um Felder zu blockieren, die Sie ausschließen möchten. Der Grund dafürInclude
ist, dass das neue Feld nicht automatisch durch eine Liste geschützt wird, wenn Sie der Entität eineExclude
neue Eigenschaft hinzufügen.Sie können das Überposten in Bearbeitungsszenarien verhindern, indem Sie zuerst die Entität aus der Datenbank lesen und dann aufrufen
TryUpdateModel
, indem Sie eine Explizite Zulässige Eigenschaftenliste übergeben. Dies ist die Methode, die in diesen Tutorials verwendet wird.Eine alternative Möglichkeit zum Verhindern von Überposting, die von vielen Entwicklern bevorzugt wird, 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. Kopieren Sie nach Abschluss des MVC-Modellbinders die Eigenschaften des Ansichtsmodells in die Entität instance, optional mithilfe eines Tools wie AutoMapper. Verwenden Sie db. Eintrag für die Entität instance, um ihren Status auf Unverändert festzulegen, und dann Eigenschaft("PropertyName") festzulegen. IsModified to true für jede Entitätseigenschaft, die im Ansichtsmodell enthalten ist. Diese Methode funktioniert sowohl im Bearbeitungsszenario als auch im Erstellungsszenario.
Neben dem
Bind
-Attribut ist dertry-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, mit dem Unterschied, dass
EditorFor
undValidationMessageFor
Hilfsprogramme für jedes Feld anstelle vonDisplayFor
verwendet werden. 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 demValidateAntiForgeryToken
-Attribut im Controller funktioniert, um siteübergreifende Angriffe auf Anforderungsfälschungen zu verhindern.In Create.cshtml sind keine Änderungen erforderlich.
Führen Sie die Seite aus, indem Sie das Programm starten, die Registerkarte Kursteilnehmer auswählen und dann auf Neu erstellen klicken.
Geben Sie Namen und ein ungültiges Datum ein, und klicken Sie auf Erstellen , um die Fehlermeldung anzuzeigen.
Dies ist die standardmäßige serverseitige Überprüfung. In einem späteren Tutorial erfahren Sie, wie Sie Attribute hinzufügen, die Code für die clientseitige Validierung 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"); }
Ändern Sie das Datum in einen gültigen Wert und klicken auf Erstellen, damit der neue Student auf der Seite Index angezeigt wird.
Schließen Sie den Browser.
Aktualisieren der HttpPost Edit-Methode
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 ohne dasHttpPost
-Attribut) dieFind
-Methode, um die ausgewählteStudent
Entität abzurufen, wie Sie in derDetails
-Methode gesehen haben. Sie müssen diese Methode nicht ändern.Diese Änderungen implementieren eine bewährte Sicherheitsmethode, um Überposting zu verhindern. The scaffolder hat ein
Bind
Attribut generiert und die vom Modellbinder erstellte Entität der Entität hinzugefügt, die mit einem Geänderten Flag festgelegt wurde. Dieser Code wird nicht mehr empfohlen, da dasBind
Attribut alle bereits vorhandenen Daten in Feldern löscht, dieInclude
nicht im Parameter aufgeführt sind. In Zukunft wird das MVC-Controllergerüst aktualisiert, sodass keine Attribute für Edit-Methoden generiertBind
werden.Der neue Code liest die vorhandene Entität und ruft auf, TryUpdateModel felder aus der Benutzereingabe in den bereitgestellten Formulardaten zu aktualisieren. 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 der Spalten, die der Benutzer nicht geändert hat. (In einem späteren Tutorial wird gezeigt, wie Parallelitätskonflikte behandelt werden. Wenn Sie nur einzelne Felder in der Datenbank aktualisieren möchten, können Sie die Entität auf EntityState.Unchanged festlegen und einzelne Felder auf EntityState.Modified festlegen.)
Um eine Überpostung 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.Infolge dieser Änderungen ist die Methodensignatur der HttpPost Edit-Methode mit der HttpGet-Edit-Methode identisch. Daher haben Sie die Methode EditPost umbenannt.
Tipp
Entitätszustände und die Attach- und SaveChanges-Methoden
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 aufAdded
festgelegt. Wenn Sie dann die SaveChanges-Methode aufrufen, gibt der Datenbankkontext einen SQL-BefehlINSERT
aus.Eine Entität kann sich in einem der folgenden Zustände befinden:
Added
. Die Entität ist noch nicht in der Datenbank vorhanden. DieSaveChanges
-Methode muss eineINSERT
Anweisung ausgeben.Unchanged
. Die MethodeSaveChanges
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. DieSaveChanges
-Methode muss eineUPDATE
Anweisung ausgeben.Deleted
. Die Entität wurde zum Löschen markiert. DieSaveChanges
-Methode muss eineDELETE
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 einer Anwendung lesen Sie eine Entität und nehmen Änderungen an einigen eigenschaftenwerten vor. Dadurch wird der Entitätsstatus automatisch auf
Modified
festgelegt. Wenn Sie dann aufrufenSaveChanges
, generiert Entity Framework eine SQL-AnweisungUPDATE
, die nur die tatsächlichen Eigenschaften aktualisiert, die Sie geändert haben.Die nicht verbundene Natur von Web-Apps lässt diese fortlaufende Sequenz nicht zu. Der DbContext , der eine Entität liest, wird verworfen, nachdem eine Seite gerendert wurde. Wenn die
HttpPost
Edit
Aktionsmethode aufgerufen wird, wird eine neue Anforderung gestellt und Sie verfügen über eine neue instance des DbContext. Daher müssen Sie den Entitätsstatus manuell aufModified.
Then festlegen, wenn Sie aufrufenSaveChanges
, 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 aktualisiert, die der Benutzer tatsächlich geändert hat, können Sie die ursprünglichen Werte in irgendeiner Weise speichern (z. B. ausgeblendete Felder), sodass sie verfügbar sind, wenn dieHttpPost
Edit
Methode aufgerufen wird. Anschließend können Sie eineStudent
Entität mit den ursprünglichen Werten erstellen, die Methode mit dieserAttach
ursprünglichen Version der Entität aufrufen, die Werte der Entität auf die neuen Werte aktualisieren und dann aufrufenSaveChanges.
Weitere Informationen finden Sie unter Entitätszustände und SpeichernÄnderungen 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.
Führen Sie die Seite aus, indem Sie das Programm starten, die Registerkarte Kursteilnehmer auswählen und dann auf einen Link Bearbeiten klicken.
Ändern Sie einige der Daten, und klicken Sie auf Speichern. Die geänderten Daten werden auf der Seite Index angezeigt.
Schließen Sie den Browser.
Aktualisieren der Seite „Delete“ (Löschen)
In Controllers\StudentController.cs verwendet der Vorlagencode für die HttpGetAttributeDelete
-Methode die Find
-Methode, um die ausgewählte Student
Entität abzurufen, wie Sie in den Details
Methoden und Edit
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 Antwort 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. Wenn dies geschieht, wird die HttpPost
Delete
-Methode aufgerufen, und dann führt diese Methode tatsächlich den Löschvorgang aus.
Sie fügen der HttpPostAttributeDelete
-Methode einen try-catch
Block hinzu, um alle Fehler zu behandeln, die beim Aktualisieren der Datenbank auftreten können. Wenn ein Fehler auftritt, ruft die HttpPostAttributeDelete
-Methode die HttpGetAttributeDelete
-Methode auf und übergibt ihr einen Parameter, der angibt, dass ein Fehler aufgetreten ist. Die HttpGetAttributeDelete
-Methode zeigt dann die Bestätigungsseite zusammen mit der Fehlermeldung erneut an, sodass der Benutzer die Möglichkeit hat, den Vorgang abzubrechen oder erneut zu versuchen.
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 ist
false
, wenn dieHttpGet
Delete
-Methode ohne vorherigen Fehler aufgerufen wird. Wenn er von derHttpPost
Delete
-Methode als Reaktion auf einen Datenbankupdatefehler aufgerufen wird, isttrue
der Parameter und eine Fehlermeldung wird an die Ansicht übergeben.Ersetzen Sie die HttpPostAttribute
Delete
Aktionsmethode (mit dem NamenDeleteConfirmed
) durch den folgenden Code, der den tatsächlichen Löschvorgang ausführt und alle Datenbankupdatefehler abfangen.[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 die status der Entität auf
Deleted
festzulegen. Beim Aufruf vonSaveChanges
wird der SQL-BefehlDELETE
generiert. Ebenfalls haben Sie den Namen der AktionsmethodeDeleteConfirmed
aufDelete
geändert. Der Gerüstcode namens dieHttpPost
Delete
-MethodeDeleteConfirmed
, um derHttpPost
Methode eine eindeutige Signatur zu verleihen. (Die CLR erfordert überladene Methoden, um unterschiedliche Methodenparameter zu haben.) Nachdem die Signaturen eindeutig sind, können Sie sich an die MVC-Konvention halten und denselben Namen für dieHttpPost
Methoden undHttpGet
Löschmethoden verwenden.Wenn die Verbesserung der Leistung in einer Anwendung mit hohem Volumen Priorität hat, können Sie eine unnötige SQL-Abfrage zum Abrufen der Zeile vermeiden, indem Sie die Codezeilen ersetzen, die die
Find
Methoden undRemove
aufrufen, durch den folgenden Code:Student studentToDelete = new Student() { ID = id }; db.Entry(studentToDelete).State = EntityState.Deleted;
Dieser Code instanziiert eine
Student
Entität nur unter Verwendung des Primärschlüsselwerts und legt dann den Entitätsstatus auf festDeleted
. 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 (bzw. das Ausführen eines Bearbeitungsvorgangs, eines Erstellungsvorgangs oder eines anderen Vorgangs, der Daten ändert) führt zu einem Sicherheitsrisiko. Weitere Informationen finden Sie unter ASP.NET MVC-Tipp #46 – Verwenden Sie keine Löschlinks, da sie Sicherheitslöcher im Blog von Stephen Walther erstellen.Fügen Sie in Views\Student\Delete.cshtml eine Fehlermeldung zwischen der
h2
Überschrift und derh3
Ü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>
Führen Sie die Seite aus, indem Sie das Programm starten, die Registerkarte Kursteilnehmer auswählen und dann auf einen Link Löschen klicken.
Wählen Sie Löschen auf der Seite mit der Meldung Sind Sie sicher, dass Sie diese Löschen möchten?.
Die Seite Index wird ohne den gelöschten Kursteilnehmer angezeigt. (Ein Beispiel für den Code zur Fehlerbehandlung in Aktion sehen Sie im Parallelitätstutorial.)
Schließen von Datenbankverbindungen
Um Datenbankverbindungen zu schließen und die darin enthaltenen Ressourcen so schnell wie möglich freizugeben, entsorgen Sie den Kontext instance, wenn Sie damit fertig sind. Aus diesem Grund stellt der Gerüstcode eine Dispose-Methode am Ende der StudentController
Klasse in StudentController.cs 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. Daher fügt dieser Code der -Methode einfach eine Überschreibung hinzuDispose(bool)
, um den Kontext explizit instance zu entsorgen.
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 Änderungen erfolgreich sind oder dass alle Änderungen 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 Benutzeroberflächenelemente für Datenfelder zu generieren. Weitere Informationen zu MVC-Hilfsprogrammen finden Sie unter Rendern eines Formulars mithilfe von HTML-Hilfsprogrammen (der Artikel gilt für MVC 3, ist aber weiterhin relevant für MVC 5).
Links zu anderen EF 6-Ressourcen finden Sie unter ASP.NET Datenzugriff – Empfohlene Ressourcen.
Nächste Schritte
In diesem Tutorial:
- Seite "Details" erstellt
- Die Seite „Erstellen“ aktualisiert
- Die HttpPost Edit-Methode wurde aktualisiert.
- Die Seite „Löschen“ aktualisiert
- Datenbankverbindungen geschlossen
- Verarbeitete Transaktionen
Fahren Sie mit dem nächsten Artikel fort, um zu erfahren, wie Sie dem Projekt Sortierung, Filterung und Paging hinzufügen.
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Tickets als Feedbackmechanismus für Inhalte auslaufen lassen und es durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unter:Feedback senden und anzeigen für