Udostępnij za pośrednictwem


Samouczek: implementowanie funkcji CRUD za pomocą platformy Entity Framework w 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 programu SQL Server LocalDB. W tym samouczku zapoznasz się i dostosujesz kod tworzenia, odczytu, aktualizowania, usuwania (CRUD), który szkielet MVC tworzy automatycznie w 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 nauce korzystania z 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óły
  • Aktualizowanie strony Tworzenie
  • Aktualizowanie metody HttpPost Edit
  • Aktualizowanie strony Usuwanie
  • Zamykanie połączeń bazy danych
  • Obsługa transakcji

Wymagania wstępne

Tworzenie strony Szczegóły

Kod szkieletu 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 obszarze Controllers\StudentController.cs metoda akcji widoku Details 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 id. Są to wartości danych trasy.

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ć w przypadku przekazania id wartości 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 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ętnego Courses ładowania dla właściwości nawigacji, więc rejestracje nie zostały pobrane w tym samym zapytaniu, które pobrało uczniów. Zamiast tego przy pierwszej próbie uzyskania dostępu Enrollments do właściwości nawigacji nowe zapytanie jest wysyłane do bazy danych w celu pobrania danych. Więcej informacji na temat leniwego ładowania i chętnego ładowania można przeczytać w samouczku Reading Related Data (Odczytywanie 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. (Jeśli naciskasz Ctrl+F5, gdy plik Details.cshtml jest otwarty, występuje 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ń ciąg "Student/Details" z adresu URL i spróbuj ponownie lub zamknij przeglądarkę, kliknij prawym przyciskiem myszy projekt, a następnie kliknij polecenie 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 obszarze Controllers\StudentController.cs zastąp metodę HttpPostAttribute Create akcji poniższym kodem. Ten kod dodaje try-catch blok i usuwa ID element 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 Student jednostkę utworzoną przez powiązanie modelu MVC ASP.NET z zestawem Students jednostek, a następnie zapisuje zmiany w bazie danych. Binder modelu odnosi się do ASP.NET funkcji MVC, która ułatwia pracę z danymi przesłanymi przez formularz; binder modelu konwertuje opublikowane wartości formularza na typy CLR i przekazuje je do metody akcji w parametrach. W takim przypadku binder modelu tworzy wystąpienie Student jednostki przy użyciu wartości właściwości z Form kolekcji.

    Usunięto ID element z atrybutu Bind, ponieważ ID jest to wartość klucza podstawowego, którą program SQL Server ustawi automatycznie po wstawieniu wiersza. Dane wejściowe od użytkownika nie ustawiają ID wartości.

    Ostrzeżenie o zabezpieczeniach — ValidateAntiForgeryToken atrybut pomaga zapobiegać fałszerzowaniu żądań między witrynami . Wymaga ona odpowiedniej Html.AntiForgeryToken() instrukcji w widoku, którą zobaczysz później.

    Atrybut Bind jest jednym ze sposobów ochrony przed nadmiernym publikowaniem w scenariuszach tworzenia. Załóżmy na przykład, że Student jednostka zawiera Secret właściwość, której nie chcesz ustawić na tej stronie 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 powiązanie modelu podczas tworzenia Student wystąpienia, powiązanie modelu będzie pobierać wartość Secret tego formularza i używać go do tworzenia 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ę Composer (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 zamierzano ustawiać tej właściwości na stronie internetowej.

    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ć. Powodem Include jest to, że po dodaniu nowej właściwości do jednostki nowe pole nie jest automatycznie chronione przez Exclude listę.

    Aby zapobiec przesłaniu w scenariuszach edycji, należy najpierw odczytać jednostkę z bazy danych, a następnie wywołać metodę TryUpdateModel, przekazując jawnie dozwoloną listę właściwości. Jest to metoda używana w tych samouczkach.

    Alternatywnym sposobem zapobiegania przesłonięć preferowanym przez wielu deweloperów jest użycie modeli wyświetlania, 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 Niezmienione, a następnie ustaw właściwość("PropertyName"). Właściwość 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ą wprowadzaną 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 dla szczegółowych informacji w temacie Monitorowanie i telemetria (tworzenie rzeczywistych aplikacji w chmurze za pomocą platformy Azure).

    Kod w pliku Views\Student\Create.cshtml jest podobny do tego, co zostało wyświetlone w pliku Details.cshtml, z tą różnicą, ż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ółdziała z atrybutem ValidateAntiForgeryToken w kontrolerze, aby zapobiec atakom fałszerzowania żą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 weryfikacja po stronie serwera, która jest domyślnie pobierana. 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 wyświetlić nowego ucznia na stronie Indeks .

  5. Zamknij okno przeglądarki.

Aktualizowanie metody HttpPost Edit

  1. 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 controllers\StudentController.csHttpGet Edit metoda (ta 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 przesłaniu, 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 metodę TryUpdateModel aktualizowania 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, że program Entity Framework tworzy instrukcje SQL w celu zaktualizowania wiersza bazy danych. 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 ustaw poszczególne pola na EntityState.Modified.

    Aby zapobiec przesłanianiu, pola, które mają być aktualizowane przez stronę Edytuj, są wymienione w parametrach TryUpdateModel . Obecnie nie ma dodatkowych pól, które są chronione, ale wyświetlanie listy pól, które mają zostać powiązane z powiązaniem modelu, gwarantuje, że w przypadku dodawania pól do modelu danych są one automatycznie chronione do momentu jawnego dodania ich w tym miejscu.

    W wyniku tych zmian sygnatura metody HttpPost Edit jest taka sama jak metoda edycji HttpGet; w związku z tym zmieniono nazwę metody EditPost.

    Napiwek

    Stany jednostek oraz 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ę stanie 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. W tej jednostce SaveChanges nie trzeba nic robić przy użyciu metody . Podczas odczytywania jednostki z bazy danych jednostka zaczyna 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 wprowadzasz 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 odczytujący jednostkę jest usuwany po renderowaniu strony. Po wywołaniu HttpPost Edit metody akcji zostanie wykonane nowe żądanie i masz nowe wystąpienie obiektu DbContext, dlatego należy 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 możliwości poznania, które właściwości zostały zmienione.

    Jeśli chcesz, aby instrukcja SQL Update aktualizował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 wywołaniu HttpPost Edit metody. Następnie możesz utworzyć jednostkę przy użyciu oryginalnych wartości, wywołać Attach metodę Student z tą oryginalną wersją jednostki, zaktualizować wartości jednostki do nowych wartości, a następnie wywołać metodę SaveChanges. Aby uzyskać więcej informacji, zobacz Stany jednostki i SaveChanges i Dane lokalne.

    Kod HTML i Razor w pliku Views\Student\Edit.cshtml jest podobny do tego, co zostało wyświetlone w pliku Create.cshtml i nie są wymagane żadne zmiany.

  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 obszarze Controllers\StudentController.cs kod szablonu metody HttpGetAttribute Delete używa Find metody do pobrania wybranej Student jednostki, jak pokazano w metodach Details i Edit . Jednak aby zaimplementować niestandardowy komunikat o błędzie, gdy wywołanie zakończy się SaveChanges niepowodzeniem, do tej metody dodasz pewne funkcje i odpowiadający jej widok.

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 daje użytkownikowi szansę zatwierdzenia lub anulowania operacji usuwania. Jeśli użytkownik go zatwierdzi, zostanie utworzone żądanie POST. W takim przypadku metoda jest wywoływana, HttpPost Delete a następnie metoda faktycznie wykonuje operację usuwania.

Do metody dodasz try-catch blok, HttpPostAttribute Delete aby obsłużyć wszelkie błędy, które mogą wystąpić po zaktualizowaniu bazy danych. Jeśli wystąpi błąd, HttpPostAttribute Delete metoda wywołuje metodę HttpGetAttribute Delete , przekazując jej parametr wskazujący, że wystąpił błąd. Następnie HttpGetAttribute Delete 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ę 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 występuje false , gdy HttpGet 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 jest true i komunikat o błędzie jest przekazywany do widoku.

  2. Zastąp metodę HttpPostAttribute Delete 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 HttpPost Delete metody DeleteConfirmed w celu nadania metodzie HttpPost unikatowego podpisu. (ClR wymaga przeciążonych metod, aby mieć 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 zwiększenie 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, które wywołają 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, co wymaga 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, operacji tworzenia lub dowolnej innej operacji, 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ą zabezpieczeń na blogu Stephena Walthera.

  3. W pliku Views\Student\Delete.cshtml dodaj komunikat o błędzie między nagłówkiem h2 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).

Zamykanie połączeń bazy danych

Aby zamknąć połączenia z bazą danych i zwolnić przechowywane zasoby tak szybko, jak to możliwe, należy usunąć wystąpienie kontekstu po zakończeniu pracy z nim. Dlatego kod szkieletowy udostępnia metodę Dispose na końcu StudentController klasy w StudentController.cs, jak pokazano w poniższym przykładzie:

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

Klasa bazowa 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 programem 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 na temat pomocników MVC, zobacz Renderowanie formularza przy użyciu pomocników HTML (artykuł dotyczy wzorca MVC 3, ale jest nadal 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óły
  • 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.