Trudny / egzaminacyjny · lekcja 16
Pełny CRUD z bazą danych w EF Core — lista produktów
Czas połączyć wszystko z poprzedniej lekcji w jeden, kompletny, DZIAŁAJĄCY przykład: pełny CRUD (Create, Read, Update, Delete) na prawdziwej bazie SQLite przez Entity Framework Core, z walidacją danych przez Data Annotations. To najbardziej praktyczny, powtarz...
Zacznij tutaj
Po co się tego uczymy?
Wprowadzenie
Teoria
Cztery operacje CRUD w Razor Pages z EF Core — każda jako osobna strona:
| Operacja | Strona | Kluczowa metoda EF Core |
|---|---|---|
| Create (utwórz) | Dodaj.cshtml | context.Produkty.Add(nowy) + SaveChangesAsync() |
| Read (odczytaj) | Lista.cshtml, Szczegoly.cshtml | ToListAsync(), FindAsync(id) |
| Update (zaktualizuj) | Edytuj.cshtml | FindAsync(id) → zmiana właściwości → SaveChangesAsync() |
| Delete (usuń) | Usun.cshtml | context.Produkty.Remove(produkt) + SaveChangesAsync() |
Wzorzec strony edycji — częsta pułapka. Strona edycji ma DWIE metody: OnGetAsync(int id) (wczytuje ISTNIEJĄCY produkt z bazy przez FindAsync(id) i wypełnia nim formularz) oraz OnPostAsync() (odbiera ZMIENIONE dane z formularza, ale musi PONOWNIE pobrać oryginalny obiekt z bazy przez jego Id, ręcznie przepisać do niego nowe wartości pól, i dopiero wtedy wywołać SaveChangesAsync()) — NIE wystarczy po prostu podstawić cały nowy obiekt z formularza w miejsce znalezionego, bo EF Core śledzi KONKRETNĄ instancję obiektu pobraną z bazy.
Strona usuwania z potwierdzeniem. Dobra praktyka UX: usuwanie NIGDY nie powinno wykonywać się od razu po kliknięciu linku (żądanie GET) — zawsze przez osobne żądanie POST z formularza z potwierdzeniem ("Czy na pewno chcesz usunąć?"), żeby przypadkowe kliknięcie linku (albo np. robot wyszukiwarki podążający za wszystkimi linkami na stronie) nie skasowało danych.
Wzorzec pobrania z obsługą "nie znaleziono". var produkt = await context.Produkty.FindAsync(id); if (produkt is null) { return NotFound(); } — ZAWSZE sprawdzaj, czy FindAsync faktycznie coś zwrócił, zanim spróbujesz odczytać jego właściwości; użytkownik mógł wpisać w adresie URL nieistniejące Id (np. /Produkty/Edytuj/9999).
Zobacz zależności
Schemat
Lista.cshtml (READ) Dodaj.cshtml (CREATE)
GET → ToListAsync() GET → pusty formularz
POST → walidacja → Add() → SaveChangesAsync()
│ │
▼ ▼
link "Edytuj" RedirectToPage("Lista")
│
▼
Edytuj.cshtml (UPDATE) Usun.cshtml (DELETE)
GET(id) → FindAsync(id) → wypełnij GET(id) → FindAsync(id) → pokaż potwierdzenie
formularz istniejącymi POST(id) → FindAsync(id) → Remove() →
danymi SaveChangesAsync()
POST → FindAsync(id) → przepisz │
nowe wartości pól → ▼
SaveChangesAsync() RedirectToPage("Lista")
│
▼
RedirectToPage("Lista")
Połącz z praktyką
Przykład z życia
Panel zarządzania produktami w sklepie internetowym — dokładnie ten zestaw czterech stron (lista, dodaj, edytuj, usuń) to jeden z najczęściej powtarzających się szablonów w praktyce zawodowej programisty webowego, niezależnie od tego, czy zarządza się produktami, klientami, zamówieniami czy artykułami na blogu.