Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
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:



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"
Öffnen Sie "Views\Student\Details.cshtml".
Jedes Feld wird mithilfe eines
DisplayForHilfsfelds 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
EnrollmentDateFeld 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 jedeEnrollmentEntität in der Eigenschaft werden der Kurstitel und die Noten angezeigt. Der Kurstitel wird von derCourseEntität abgerufen, die in derCourseNavigationseigenschaft derEnrollmentsEntitä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 dieCoursesNavigationseigenschaft angegeben, sodass die Registrierungen nicht in derselben Abfrage abgerufen wurden, die die Kursteilnehmer erhalten hat. Stattdessen wird beim ersten Versuch, auf dieEnrollmentsNavigationseigenschaft 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.Ö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.
Schließen Sie den Browser.
Aktualisieren der Seite „Erstellen“
Ersetzen Sie in Controller\StudentController.cs die HttpPostAttribute
CreateAktionsmethode durch den folgenden Code. Dieser Code fügt einentry-catchBlock hinzu und entferntIDaus 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
Studententität, die vom ASP.NET MVC-Modellbinder erstellt wurde, zumStudentsEntitä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 eineStudentEntität für Sie mithilfe von Eigenschaftswerten aus derFormAuflistung.Sie haben das Bind-Attribut entfernt
ID, daIDes sich um den Primärschlüsselwert handelt, den SQL Server beim Einfügen der Zeile automatisch festlegt. Die Eingabe des Benutzers legt denIDWert nicht fest.Sicherheitswarnung – Das
ValidateAntiForgeryTokenAttribut verhindert websiteübergreifende Fälschungsangriffe . Sie erfordert eine entsprechendeHtml.AntiForgeryToken()Anweisung in der Ansicht, die Sie später sehen werden.Das
BindAttribut ist eine Möglichkeit, um vor Überbuchungen in Erstellungsszenarien zu schützen. Angenommen, dieStudentEntität enthält eineSecretEigenschaft, 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 einenSecretFormularwert zu veröffentlichen. Ohne das BindAttribute Attribut, das die Felder beschränkt, die der Modellordner beim Erstellen einerStudentInstanz verwendet, würde der Modellordner diesenSecretFormularwert aufnehmen und zum Erstellen der EntitätsinstanzStudentverwenden. Dann würde jeder beliebige Wert in Ihre Datenbank aktualisiert werden, den der Hacker für das FormularfeldSecretfestlegt. Die folgende Abbildung zeigt das Fiddler-Tool, das dasSecretFeld (mit dem Wert "OverPost") zu den geposteten Formularwerten hinzufügt.
Der Wert „OverPost“ würde dann erfolgreich der Eigenschaft
Secretder eingefügten Zeile hinzugefügt werden, obwohl Sie nie beabsichtigt haben, dass die Webseite diese Eigenschaft festlegen kann.Es ist am besten, den
IncludeParameter mit demBindAttribut zum expliziten Auflisten von Feldern zu verwenden. Es ist auch möglich, den Parameter zum Blockieren vonExcludeFeldern zu verwenden, die Sie ausschließen möchten. Der GrundIncludedafür ist, dass das neue Feld nicht automatisch durch eineExcludeListe 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
BindAttribut ist dertry-catchBlock 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
EditorForundValidationMessageForHilfsprogramme für jedes Feld anstelle vonDisplayFor. 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 demValidateAntiForgeryTokenAttribut im Controller funktioniert, um websiteübergreifende Anforderungsverfälschungsangriffe 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 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"); }Ä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.
Update HttpPost Edit-Methode
Ersetzen Sie die HttpPostAttribute
EditAktionsmethode 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 EditMethode (die methode ohne dasHttpPostAttribut) dieFindMethode, um die ausgewählteStudentEntität abzurufen, wie Sie in derDetailsMethode 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
BindAttribut 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 dasBindAttribut bereits vorhandene Daten in Feldern löscht, dieIncludenicht im Parameter aufgeführt sind. In Zukunft wird das MVC-Controllergerüst aktualisiert, sodass es keine Attribute für Edit-Methoden generiertBind.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
TryUpdateModelParametern 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
SaveChangesaufrufen. 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-BefehlINSERTaus.Eine Entität kann einen der folgenden Status aufweisen:
Added. Die Entität ist in der Datenbank noch nicht vorhanden. DieSaveChangesMethode muss eineINSERTAnweisung ausgeben.Unchanged. Die MethodeSaveChangesmuss 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. DieSaveChangesMethode muss eineUPDATEAnweisung ausgeben.Deleted. Die Entität wurde zum Löschen markiert. DieSaveChangesMethode muss eineDELETEAnweisung 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
Modifiedfestgelegt. Wenn Sie dann aufrufenSaveChanges, generiert Das Entity Framework eine SQL-AnweisungUPDATE, 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
HttpPostEditAktionsmethode aufgerufen wird, wird eine neue Anforderung gestellt, und Sie haben eine neue Instanz des DbContext, sodass Sie den EntitätsstatusModified.manuell auf "Then" festlegen müssen, 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
Updatenur 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 derHttpPostEditMethode verfügbar sind. Anschließend können Sie eineStudentEntität mit den ursprünglichen Werten erstellen, die Methode mit dieserAttachursprünglichen Version der Entität aufrufen, die Werte der Entität auf die neuen Werte aktualisieren und dannSaveChanges.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.
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 Indexseite angezeigt.
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.
Ersetzen Sie die HttpGetAttribute
DeleteAktionsmethode 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
falseaufgerufen, wenn dieHttpGetDeleteMethode ohne vorherigen Fehler aufgerufen wird. Wenn sie von derHttpPostDeleteMethode als Reaktion auf einen Datenbankaktualisierungsfehler aufgerufen wird, wirdtrueder Parameter und eine Fehlermeldung an die Ansicht übergeben.Ersetzen Sie die HttpPostAttribute
DeleteAktionsmethode (benanntDeleteConfirmed) 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 vonSaveChangeswird der SQL-BefehlDELETEgeneriert. Ebenfalls haben Sie den Namen der AktionsmethodeDeleteConfirmedaufDeletegeändert. Der Gerüstcode namens derHttpPostDeleteMethode, um derHttpPostMethodeDeleteConfirmedeine 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 dieHttpPostMethoden undHttpGetLö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
FindUndRemoveMethoden durch den folgenden Code aufrufen:Student studentToDelete = new Student() { ID = id }; db.Entry(studentToDelete).State = EntityState.Deleted;Dieser Code instanziiert eine
StudentEntität nur mit dem Primärschlüsselwert und legt dann den Entitätsstatus aufDeleted. Das ist alles, was Entity Framework benötigt, um die Entität löschen zu können.Wie bereits erwähnt, löscht die
HttpGetDeleteMethode 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.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 "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.