Udostępnij za pośrednictwem


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:

Zrzut ekranu przedstawiający stronę szczegółów ucznia.

Zrzut ekranu przedstawiający stronę tworzenia ucznia.

Zrzut ekranu przedstawiający stronę usuwania ucznia.

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, actioni 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 controllerwartoś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

  1. 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>
    
  2. 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żdej Enrollment jednostki we właściwości wyświetla tytuł kursu i ocenę. Tytuł kursu jest pobierany z Course jednostki przechowywanej Course we właściwości Enrollments 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ęp Enrollments 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.

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

  4. Zamknij okno przeglądarki.

Aktualizowanie strony Tworzenie

  1. W pliku Controllers\StudentController.cs zastąp metodę HttpPostAttributeCreate akcji poniższym kodem. Ten kod dodaje try-catch blok i usuwa ID 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 zestawem Students 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ąpienie Student jednostki przy użyciu wartości właściwości z kolekcji Form .

    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 odpowiedniej Html.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 jednostka Student zawiera Secret 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 tworzenia Studentwystąpienia powiązanie modelu spowoduje odebranie tej Secret wartości formularza i użycie jej do utworzenia Student wystąpienia jednostki. Następnie dowolna wartość określona przez hakera Secret dla pola formularza zostanie zaktualizowana w bazie danych. Na poniższej ilustracji przedstawiono narzędzie fiddler dodające Secret pole (z wartością "OverPost") do opublikowanych wartości formularza.

    Zrzut ekranu przedstawiający kartę Kompozytor. W prawym górnym rogu polecenie Wykonaj jest zakreśline na czerwono. W prawym dolnym rogu wpis tajny jest równy Over Post jest zakreśliny na czerwono.

    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 atrybutem Bind , 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 przez Exclude 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 Bindtry-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 i ValidationMessageFor pomocnicy są używane dla każdego pola zamiast DisplayFor. 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 atrybutem ValidateAntiForgeryToken w kontrolerze, aby zapobiec atakom fałszowania żądań między witrynami .

    W pliku Create.cshtml nie są wymagane żadne zmiany.

  2. Uruchom stronę, uruchamiając program, wybierając kartę Uczniowie , a następnie klikając pozycję Utwórz nowy.

  3. 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");
    }
    
  4. Zmień datę na prawidłową wartość i kliknij przycisk Utwórz , aby zobaczyć nowego ucznia na stronie Indeks .

  5. Zamknij okno przeglądarki.

Aktualizowanie metody HttpPost Edit

  1. Zastąp metodę HttpPostAttributeEdit 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.csHttpGet Edit metoda (bez atrybutuHttpPost) używa Find metody do pobrania wybranej Student jednostki, jak pokazano w metodzie Details . 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 parametrze Include . 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 na Addedwartość . Następnie po wywołaniu metody SaveChanges kontekst bazy danych wystawia polecenie SQL INSERT .

    Jednostka może znajdować się w jednym z następujących stanów:

    • Added. Jednostka nie istnieje jeszcze w bazie danych. Metoda SaveChanges 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. Metoda SaveChanges musi wydać instrukcję UPDATE .
    • Deleted. Jednostka została oznaczona do usunięcia. Metoda SaveChanges 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łaniu SaveChangesmetody program Entity Framework generuje instrukcję SQL UPDATE , 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 HttpPostEdit metody akcji zostanie wykonane nowe żądanie i masz nowe wystąpienie obiektu DbContext, więc musisz ręcznie ustawić stan jednostki na Modified. Wartość Następnie po wywołaniu SaveChangesprogramu 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 po HttpPostEdit 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łanie SaveChanges. 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.

  2. Uruchom stronę, uruchamiając program, wybierając kartę Uczniowie , a następnie klikając hiperlink Edytuj .

  3. Zmień niektóre dane i kliknij przycisk Zapisz. Zmienione dane są widoczne na stronie Indeks.

  4. 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, HttpPostDelete 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.

  1. Zastąp metodę HttpGetAttributeDelete 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, gdy HttpGetDelete metoda jest wywoływana bez wcześniejszego błędu. Gdy jest wywoływana przez metodę HttpPostDelete w odpowiedzi na błąd aktualizacji bazy danych, parametr jest true i komunikat o błędzie jest przekazywany do widoku.

  2. Zastąp metodę HttpPostAttributeDelete akcji (o nazwie DeleteConfirmed) 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. Po SaveChanges wywołaniu jest generowane polecenie SQL DELETE . Zmieniono również nazwę metody akcji z DeleteConfirmed na Delete. Kod szkieletowy o nazwie HttpPostDelete metoda DeleteConfirmed w celu nadania HttpPost 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 dla HttpPost metod i HttpGet 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 i Remove 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 na Deleted. To wszystko, którego potrzebuje program Entity Framework w celu usunięcia jednostki.

    Jak wspomniano, HttpGetDelete 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.

  3. W pliku Views\Student\Delete.cshtml dodaj komunikat o błędzie między h2 nagłówkiem a nagłówkiem h3 , 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>
    
  4. Uruchom stronę, uruchamiając program, wybierając kartę Uczniowie , a następnie klikając hiperlink Usuń .

  5. 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 SaveChangesmetodę , 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.