Samouczek: implementowanie funkcji CRUD za pomocą platformy Entity Framework w usłudze ASP.NET MVC
W poprzednim samouczku utworzono aplikację MVC, która przechowuje i wyświetla dane przy użyciu programu Entity Framework (EF) 6 i SQL Server LocalDB. W tym samouczku zapoznasz się z kodem tworzenia, odczytywania, aktualizowania, usuwania (CRUD), który szkielet MVC jest tworzony automatycznie na kontrolerach i widokach.
Uwaga
Typowym rozwiązaniem jest zaimplementowanie wzorca repozytorium w celu utworzenia warstwy abstrakcji między kontrolerem a warstwą dostępu do danych. Aby zachować prostotę tych samouczków i skupić się na uczeniu, jak używać samej platformy EF 6, nie używają repozytoriów. Aby uzyskać informacje o sposobie implementowania repozytoriów, zobacz ASP.NET Mapa zawartości dostępu do danych.
Oto przykłady tworzonych stron internetowych:
W tym samouczku zostały wykonane następujące czynności:
- Tworzenie strony Szczegółów
- Aktualizowanie strony Tworzenie
- Aktualizowanie metody HttpPost Edit
- Aktualizowanie strony Usuwanie
- Zamknij Połączenia z bazą danych
- Obsługa transakcji
Wymagania wstępne
Tworzenie strony Szczegółów
Kod szkieletowy strony Uczniowie Index
pominął Enrollments
właściwość, ponieważ ta właściwość zawiera kolekcję. Details
Na stronie zostanie wyświetlona zawartość kolekcji w tabeli HTML.
W pliku Controllers\StudentController.cs metoda akcji dla Details
widoku używa metody Find do pobrania pojedynczej Student
jednostki.
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);
}
Wartość klucza jest przekazywana do metody jako parametru id
i pochodzi z danych trasy w hiperlinku Szczegóły na stronie Indeks.
Porada: Dane trasy
Dane trasy to dane, które powiązanie modelu można znaleźć w segmencie adresu URL określonym w tabeli routingu. Na przykład trasa domyślna określa controller
, action
i id
segmenty:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
W poniższym adresie URL domyślna trasa mapuje Instructor
jako controller
wartości , Index
jako action
wartości i 1 jako id
; są to wartości danych trasowania.
http://localhost:1230/Instructor/Index/1?courseID=2021
?courseID=2021
jest wartością ciągu zapytania. Powiązanie modelu będzie również działać, jeśli przekażesz id
jako wartość ciągu zapytania:
http://localhost:1230/Instructor/Index?id=1&CourseID=2021
Adresy URL są tworzone przez ActionLink
instrukcje w widoku Razor. W poniższym kodzie id
parametr jest zgodny z trasą domyślną, dlatego id
jest dodawany do danych trasy.
@Html.ActionLink("Select", "Index", new { id = item.PersonID })
W poniższym kodzie courseID
parametr nie jest zgodny z parametrem w trasie domyślnej, dlatego jest dodawany jako ciąg zapytania.
@Html.ActionLink("Select", "Index", new { courseID = item.CourseID })
Aby utworzyć stronę Szczegóły
Otwórz plik Views\Student\Details.cshtml.
Każde pole jest wyświetlane przy użyciu
DisplayFor
pomocnika, jak pokazano w poniższym przykładzie:<dt> @Html.DisplayNameFor(model => model.LastName) </dt> <dd> @Html.DisplayFor(model => model.LastName) </dd>
EnrollmentDate
Po polu i bezpośrednio przed tagiem zamykającym</dl>
dodaj wyróżniony kod, aby wyświetlić listę rejestracji, jak pokazano w poniższym przykładzie:<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>
Jeśli wcięcie kodu jest nieprawidłowe po wklejeniu kodu, naciśnij klawisze Ctrl+K, Ctrl+D , aby go sformatować.
Ten kod przechodzi przez jednostki we
Enrollments
właściwości nawigacji. Dla każdejEnrollment
jednostki we właściwości wyświetla tytuł kursu i ocenę. Tytuł kursu jest pobierany zCourse
jednostki przechowywanejCourse
we właściwościEnrollments
nawigacji jednostki. Wszystkie te dane są pobierane z bazy danych automatycznie, gdy są potrzebne. Innymi słowy, używasz tutaj leniwego ładowania. Nie określono chętnegoCourses
ładowania dla właściwości nawigacji, więc rejestracje nie zostały pobrane w tym samym zapytaniu, które otrzymało uczniów. Zamiast tego po raz pierwszy próbujesz uzyskać dostępEnrollments
do właściwości nawigacji, nowe zapytanie jest wysyłane do bazy danych w celu pobrania danych. Więcej informacji na temat ładowania leniwego i chętnego ładowania można przeczytać w samouczku Dotyczącym powiązanych danych w dalszej części tej serii.Otwórz stronę Szczegóły, uruchamiając program (Ctrl+F5), wybierając kartę Uczniowie , a następnie klikając link Szczegóły dla Alexander Carson. (W przypadku naciśnięcia klawisza Ctrl+F5 , gdy plik Details.cshtml jest otwarty, zostanie wyświetlony błąd HTTP 400. Dzieje się tak, ponieważ program Visual Studio próbuje uruchomić stronę Szczegóły, ale nie został osiągnięty z linku określającego ucznia do wyświetlenia. Jeśli tak się stanie, usuń element "Student/Szczegóły" z adresu URL i spróbuj ponownie lub zamknij przeglądarkę, kliknij prawym przyciskiem myszy projekt, a następnie kliknij pozycję Wyświetl>widok w przeglądarce.
Zostanie wyświetlona lista kursów i ocen dla wybranego ucznia.
Zamknij okno przeglądarki.
Aktualizowanie strony Tworzenie
W pliku Controllers\StudentController.cs zastąp metodę HttpPostAttribute
Create
akcji poniższym kodem. Ten kod dodajetry-catch
blok i usuwaID
z atrybutu BindAttribute dla metody szkieletowej:[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); }
Ten kod dodaje jednostkę utworzoną
Student
przez powiązanie modelu ASP.NET MVC z zestawemStudents
jednostek, a następnie zapisuje zmiany w bazie danych. Binder modelu odnosi się do funkcji ASP.NET MVC, która ułatwia pracę z danymi przesłanymi przez formularz; binder modelu konwertuje wartości formularzy opublikowanych na typy CLR i przekazuje je do metody akcji w parametrach. W tym przypadku binder modelu tworzy wystąpienieStudent
jednostki przy użyciu wartości właściwości z kolekcjiForm
.ID
Usunięto element z atrybutu Bind, ponieważID
jest to wartość klucza podstawowego, która SQL Server zostanie ustawiona automatycznie po wstawieniu wiersza. Dane wejściowe od użytkownika nie ustawiająID
wartości.Ostrzeżenie o zabezpieczeniach —
ValidateAntiForgeryToken
atrybut pomaga zapobiegać atakom fałszerowania żądań między witrynami . Wymaga ona odpowiedniejHtml.AntiForgeryToken()
instrukcji w widoku, która będzie widoczna później.Atrybut
Bind
jest jednym ze sposobów ochrony przed nadmiernym publikowaniem w scenariuszach tworzenia. Załóżmy na przykład, że jednostkaStudent
zawieraSecret
właściwość, którą nie chcesz ustawić tej strony sieci Web.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; } }
Nawet jeśli nie masz
Secret
pola na stronie internetowej, haker może użyć narzędzia takiego jak fiddler lub napisać jakiś kod JavaScript, aby opublikowaćSecret
wartość formularza. BindAttribute Bez ograniczania pól używanych przez binder modelu podczas tworzeniaStudent
wystąpienia powiązanie modelu spowoduje odebranie tejSecret
wartości formularza i użycie jej do utworzeniaStudent
wystąpienia jednostki. Następnie dowolna wartość określona przez hakeraSecret
dla pola formularza zostanie zaktualizowana w bazie danych. Na poniższej ilustracji przedstawiono narzędzie fiddler dodająceSecret
pole (z wartością "OverPost") do opublikowanych wartości formularza.Następnie wartość "OverPost" zostanie pomyślnie dodana do
Secret
właściwości wstawionego wiersza, chociaż nigdy nie zamierzono, aby strona internetowa mogła ustawić te właściwości.Najlepiej użyć parametru
Include
z atrybutemBind
, aby jawnie wyświetlić listę pól. Można również użyć parametru ,Exclude
aby zablokować pola, które chcesz wykluczyć.Include
Przyczyną jest bezpieczniejsza jest to, że po dodaniu nowej właściwości do jednostki nowe pole nie jest automatycznie chronione przezExclude
listę.Aby zapobiec zastępowaniu w scenariuszach edycji, należy najpierw odczytać jednostkę z bazy danych, a następnie wywołać metodę
TryUpdateModel
, przekazując jawną dozwoloną listę właściwości. Jest to metoda używana w tych samouczkach.Alternatywnym sposobem zapobiegania przesłanianiu preferowanym przez wielu deweloperów jest użycie modeli widoku, a nie klas jednostek z powiązaniem modelu. Uwzględnij tylko właściwości, które chcesz zaktualizować w modelu widoku. Po zakończeniu powiązania modelu MVC skopiuj właściwości modelu widoku do wystąpienia jednostki, opcjonalnie przy użyciu narzędzia takiego jak AutoMapper. Użyj bazy danych. Wpis w wystąpieniu jednostki, aby ustawić jego stan na Bez zmian, a następnie ustaw właściwość("PropertyName"). IsModified ma wartość true dla każdej właściwości jednostki uwzględnionej w modelu widoku. Ta metoda działa zarówno w scenariuszach edycji, jak i tworzenia.
Poza atrybutem
Bind
try-catch
blok jest jedyną zmianą wprowadzoną w kodzie szkieletowym. Jeśli podczas zapisywania zmian zostanie przechwycony DataException wyjątek, z którego pochodzą zmiany, zostanie wyświetlony ogólny komunikat o błędzie. DataException wyjątki są czasami spowodowane przez coś zewnętrznego dla aplikacji, a nie błąd programowania, dlatego zaleca się, aby użytkownik próbował ponownie. Chociaż nie zaimplementowano w tym przykładzie, aplikacja jakości produkcyjnej rejestruje wyjątek. Aby uzyskać więcej informacji, zobacz sekcję Dziennik na potrzeby szczegółowych informacji w temacie Monitorowanie i telemetria (tworzenie Real-World aplikacji w chmurze za pomocą platformy Azure).Kod w pliku Views\Student\Create.cshtml jest podobny do tego, co pokazano w pliku Details.cshtml, z wyjątkiem tego, że
EditorFor
iValidationMessageFor
pomocnicy są używane dla każdego pola zamiastDisplayFor
. Oto odpowiedni kod:<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>
Plik Create.cshtml zawiera
@Html.AntiForgeryToken()
również element , który współpracuje z atrybutemValidateAntiForgeryToken
w kontrolerze, aby zapobiec atakom fałszowania żądań między witrynami .W pliku Create.cshtml nie są wymagane żadne zmiany.
Uruchom stronę, uruchamiając program, wybierając kartę Uczniowie , a następnie klikając pozycję Utwórz nowy.
Wprowadź nazwy i nieprawidłową datę, a następnie kliknij przycisk Utwórz , aby wyświetlić komunikat o błędzie.
Jest to domyślnie walidacja po stronie serwera. W późniejszym samouczku dowiesz się, jak dodać atrybuty generujące kod na potrzeby weryfikacji po stronie klienta. Poniższy wyróżniony kod przedstawia sprawdzanie poprawności modelu w metodzie Create .
if (ModelState.IsValid) { db.Students.Add(student); db.SaveChanges(); return RedirectToAction("Index"); }
Zmień datę na prawidłową wartość i kliknij przycisk Utwórz , aby zobaczyć nowego ucznia na stronie Indeks .
Zamknij okno przeglądarki.
Aktualizowanie metody HttpPost Edit
Zastąp metodę HttpPostAttribute
Edit
akcji następującym kodem:[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); }
Uwaga
W pliku Controllers\StudentController.cs
HttpGet Edit
metoda (bez atrybutuHttpPost
) używaFind
metody do pobrania wybranejStudent
jednostki, jak pokazano w metodzieDetails
. Nie musisz zmieniać tej metody.Te zmiany implementują najlepsze rozwiązanie w zakresie zabezpieczeń, aby zapobiec przestępowaniu, szkielet wygenerował atrybut i dodał jednostkę utworzoną
Bind
przez binder modelu do zestawu jednostek z flagą Zmodyfikowana. Ten kod nie jest już zalecany, ponieważBind
atrybut usuwa wszystkie istniejące dane w polach, które nie są wymienione w parametrzeInclude
. W przyszłości szkielet kontrolera MVC zostanie zaktualizowany tak, aby nie generowałBind
atrybutów dla metod Edycji.Nowy kod odczytuje istniejącą jednostkę i wywołuje wywołanie TryUpdateModel w celu zaktualizowania pól z danych wejściowych użytkownika w opublikowanych danych formularza. Automatyczne śledzenie zmian w programie Entity Framework ustawia flagę EntityState.Modified w jednostce. Po wywołaniu metody SaveChanges flaga Modified powoduje utworzenie instrukcji SQL w celu zaktualizowania wiersza bazy danych przez program Entity Framework. Konflikty współbieżności są ignorowane, a wszystkie kolumny wiersza bazy danych są aktualizowane, w tym te, które użytkownik nie zmienił. (W późniejszym samouczku pokazano, jak obsługiwać konflikty współbieżności, a jeśli chcesz zaktualizować tylko poszczególne pola w bazie danych, możesz ustawić jednostkę na EntityState.Bez zmian i ustawić poszczególne pola na EntityState.Modified).
Aby zapobiec przesłanianiu, pola, które mają być aktualizowane przez stronę Edytuj, są wyświetlane w
TryUpdateModel
parametrach. Obecnie nie ma żadnych dodatkowych pól, które są chronione, ale lista pól, które mają zostać powiązane przez powiązanie modelu, gwarantuje, że w przypadku dodawania pól do modelu danych są automatycznie chronione, dopóki nie zostaną jawnie dodane tutaj.W wyniku tych zmian sygnatura metody HttpPost Edit jest taka sama jak metoda edycji HttpGet; w związku z tym zmieniono nazwę metody EditPost.
Porada
Stany jednostek i metody Attach i SaveChanges
Kontekst bazy danych śledzi, czy jednostki w pamięci są zsynchronizowane z odpowiednimi wierszami w bazie danych, a te informacje określają, co się dzieje po wywołaniu
SaveChanges
metody. Na przykład po przekazaniu nowej jednostki do metody Add stan tej jednostki jest ustawiony naAdded
wartość . Następnie po wywołaniu metody SaveChanges kontekst bazy danych wystawia polecenie SQLINSERT
.Jednostka może znajdować się w jednym z następujących stanów:
Added
. Jednostka nie istnieje jeszcze w bazie danych. MetodaSaveChanges
musi wydać instrukcjęINSERT
.Unchanged
. Nie trzeba nic robić z tą jednostkąSaveChanges
za pomocą metody . Podczas odczytywania jednostki z bazy danych jednostka rozpoczyna się od tego stanu.Modified
. Niektóre lub wszystkie wartości właściwości jednostki zostały zmodyfikowane. MetodaSaveChanges
musi wydać instrukcjęUPDATE
.Deleted
. Jednostka została oznaczona do usunięcia. MetodaSaveChanges
musi wydać instrukcjęDELETE
.Detached
. Jednostka nie jest śledzona przez kontekst bazy danych.
W aplikacji klasycznej zmiany stanu są zwykle ustawiane automatycznie. W typie aplikacji klasycznej odczytujesz jednostkę i wprowadzisz zmiany w niektórych jej wartościach właściwości. Powoduje to automatyczne zmianę stanu jednostki na
Modified
. Następnie po wywołaniuSaveChanges
metody program Entity Framework generuje instrukcję SQLUPDATE
, która aktualizuje tylko rzeczywiste właściwości, które uległy zmianie.Rozłączony charakter aplikacji internetowych nie zezwala na tę sekwencję ciągłą. Obiekt DbContext, który odczytuje jednostkę, jest usuwany po renderowaniu strony. Po wywołaniu
HttpPost
Edit
metody akcji zostanie wykonane nowe żądanie i masz nowe wystąpienie obiektu DbContext, więc musisz ręcznie ustawić stan jednostki naModified.
Wartość Następnie po wywołaniuSaveChanges
programu Entity Framework aktualizuje wszystkie kolumny wiersza bazy danych, ponieważ kontekst nie ma sposobu, aby wiedzieć, które właściwości zostały zmienione.Jeśli chcesz, aby instrukcja SQL
Update
zaktualizowała tylko pola, które użytkownik rzeczywiście zmienił, możesz zapisać oryginalne wartości w jakiś sposób (na przykład ukryte pola), aby były dostępne poHttpPost
Edit
wywołaniu metody. Następnie możesz utworzyćStudent
jednostkę przy użyciu oryginalnych wartości, wywołaćAttach
metodę z tą oryginalną wersją jednostki, zaktualizować wartości jednostki do nowych wartości, a następnie wywołać wywołanieSaveChanges.
Aby uzyskać więcej informacji, zobacz Stany jednostek i SaveChanges i Dane lokalne.Kod HTML i Razor w pliku Views\Student\Edit.cshtml jest podobny do tego, co pokazano w pliku Create.cshtml, a żadne zmiany nie są wymagane.
Uruchom stronę, uruchamiając program, wybierając kartę Uczniowie , a następnie klikając hiperlink Edytuj .
Zmień niektóre dane i kliknij przycisk Zapisz. Zmienione dane są widoczne na stronie Indeks.
Zamknij okno przeglądarki.
Aktualizowanie strony Usuwanie
W pliku Controllers\StudentController.cs kod HttpGetAttributeDelete
szablonu metody używa Find
metody do pobrania wybranej Student
jednostki, jak pokazano w metodach Details
i Edit
. Jednak w celu zaimplementowania niestandardowego komunikatu o błędzie, gdy wywołanie SaveChanges
zakończy się niepowodzeniem, dodasz pewne funkcje do tej metody i odpowiedniego widoku.
Jak pokazano na potrzeby operacji aktualizacji i tworzenia, operacje usuwania wymagają dwóch metod akcji. Metoda wywoływana w odpowiedzi na żądanie GET wyświetla widok, który umożliwia użytkownikowi zatwierdzenie lub anulowanie operacji usuwania. Jeśli użytkownik go zatwierdzi, zostanie utworzone żądanie POST. W takim przypadku metoda jest wywoływana, HttpPost
Delete
a następnie ta metoda rzeczywiście wykonuje operację usuwania.
Do metody dodasz try-catch
blok, HttpPostAttributeDelete
aby obsłużyć wszelkie błędy, które mogą wystąpić po zaktualizowaniu bazy danych. Jeśli wystąpi błąd, HttpPostAttributeDelete
metoda wywołuje metodę HttpGetAttributeDelete
, przekazując jej parametr wskazujący, że wystąpił błąd. Następnie HttpGetAttributeDelete
metoda redisplays strony potwierdzenia wraz z komunikatem o błędzie, dając użytkownikowi możliwość anulowania lub próby ponownie.
Zastąp metodę HttpGetAttribute
Delete
akcji następującym kodem, który zarządza raportowaniem błędów: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); }
Ten kod akceptuje opcjonalny parametr wskazujący, czy metoda została wywołana po niepowodzeniu zapisywania zmian. Ten parametr jest
false
wtedy, gdyHttpGet
Delete
metoda jest wywoływana bez wcześniejszego błędu. Gdy jest wywoływana przez metodęHttpPost
Delete
w odpowiedzi na błąd aktualizacji bazy danych, parametr jesttrue
i komunikat o błędzie jest przekazywany do widoku.Zastąp metodę HttpPostAttribute
Delete
akcji (o nazwieDeleteConfirmed
) następującym kodem, który wykonuje rzeczywistą operację usuwania i przechwytuje wszelkie błędy aktualizacji bazy danych.[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"); }
Ten kod pobiera wybraną jednostkę, a następnie wywołuje metodę Remove , aby ustawić stan jednostki na
Deleted
. PoSaveChanges
wywołaniu jest generowane polecenie SQLDELETE
. Zmieniono również nazwę metody akcji zDeleteConfirmed
naDelete
. Kod szkieletowy o nazwieHttpPost
Delete
metodaDeleteConfirmed
w celu nadaniaHttpPost
metodzie unikatowego podpisu. (ClR wymaga przeciążonych metod, aby miały różne parametry metody). Teraz, gdy podpisy są unikatowe, możesz trzymać się konwencji MVC i używać tej samej nazwy dlaHttpPost
metod iHttpGet
usuwania.Jeśli poprawa wydajności w aplikacji o dużej ilości jest priorytetem, można uniknąć niepotrzebnego zapytania SQL w celu pobrania wiersza, zastępując wiersze kodu wywołującego
Find
metody iRemove
następującym kodem:Student studentToDelete = new Student() { ID = id }; db.Entry(studentToDelete).State = EntityState.Deleted;
Ten kod tworzy wystąpienie
Student
jednostki przy użyciu tylko wartości klucza podstawowego, a następnie ustawia stan jednostki naDeleted
. To wszystko, którego potrzebuje program Entity Framework w celu usunięcia jednostki.Jak wspomniano,
HttpGet
Delete
metoda nie usuwa danych. Wykonanie operacji usuwania w odpowiedzi na żądanie GET (lub w tym przypadku wykonanie dowolnej operacji edycji, operację tworzenia lub inną operację, która zmienia dane) powoduje zagrożenie bezpieczeństwa. Aby uzyskać więcej informacji, zobacz ASP.NET MVC Tip #46 — Nie używaj linków usuwania, ponieważ tworzą luki w zabezpieczeniach na blogu Stephena Walthera.W pliku Views\Student\Delete.cshtml dodaj komunikat o błędzie między
h2
nagłówkiem a nagłówkiemh3
, jak pokazano w poniższym przykładzie:<h2>Delete</h2> <p class="error">@ViewBag.ErrorMessage</p> <h3>Are you sure you want to delete this?</h3>
Uruchom stronę, uruchamiając program, wybierając kartę Uczniowie , a następnie klikając hiperlink Usuń .
Wybierz pozycję Usuń na stronie z informacją Czy na pewno chcesz to usunąć?.
Strona Indeks jest wyświetlana bez usuniętego ucznia. (W samouczku współbieżności zostanie wyświetlony przykład kodu obsługi błędów).
Zamknij Połączenia z bazą danych
Aby zamknąć Połączenia z bazą danych i zwolnić przechowywane zasoby tak szybko, jak to możliwe, po zakończeniu usuwania wystąpienia kontekstu. Dlatego kod szkieletowy udostępnia metodę Dispose na końcu StudentController
klasy w pliku StudentController.cs, jak pokazano w poniższym przykładzie:
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
Klasa podstawowa Controller
już implementuje IDisposable
interfejs, więc ten kod po prostu dodaje przesłonięcia do Dispose(bool)
metody w celu jawnego usunięcia wystąpienia kontekstu.
Obsługa transakcji
Domyślnie program Entity Framework niejawnie implementuje transakcje. W scenariuszach, w których wprowadzasz zmiany w wielu wierszach lub tabelach, a następnie wywołujesz SaveChanges
metodę , program Entity Framework automatycznie upewnia się, że wszystkie zmiany kończą się powodzeniem lub wszystkimi niepowodzeniem. Jeśli najpierw zostaną wykonane pewne zmiany, a następnie wystąpi błąd, te zmiany zostaną automatycznie wycofane. W przypadku scenariuszy, w których potrzebujesz większej kontroli — na przykład jeśli chcesz uwzględnić operacje wykonywane poza platformą Entity Framework w transakcji, zobacz Praca z transakcjami.
Uzyskiwanie kodu
Pobieranie ukończonego projektu
Dodatkowe zasoby
Masz teraz kompletny zestaw stron, które wykonują proste operacje CRUD dla Student
jednostek. Użyto pomocników MVC do generowania elementów interfejsu użytkownika dla pól danych. Aby uzyskać więcej informacji o pomocnikach MVC, zobacz Renderowanie formularza przy użyciu pomocników HTML (artykuł dotyczy wzorca MVC 3, ale nadal jest odpowiedni dla MVC 5).
Linki do innych zasobów ef 6 można znaleźć w ASP.NET Dostęp do danych — zalecane zasoby.
Następne kroki
W tym samouczku zostały wykonane następujące czynności:
- Utworzono stronę Szczegółów
- Zaktualizowano stronę Tworzenie
- Zaktualizowano metodę HttpPost Edit
- Zaktualizowano stronę Usuwanie
- Zamknięte Połączenia z bazą danych
- Obsługiwane transakcje
Przejdź do następnego artykułu, aby dowiedzieć się, jak dodać sortowanie, filtrowanie i stronicowanie do projektu.
Opinia
https://aka.ms/ContentUserFeedback.
Dostępne już wkrótce: W 2024 r. będziemy stopniowo wycofywać zgłoszenia z serwisu GitHub jako mechanizm przesyłania opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla