Kurz: Implementace funkcí CRUD pomocí entity Framework v ASP.NET MVC
V předchozím kurzu jste vytvořili aplikaci MVC, která ukládá a zobrazuje data pomocí Entity Frameworku (EF) 6 a SQL Server LocalDB. V tomto kurzu zkontrolujete a přizpůsobíte kód vytvoření, čtení, aktualizace, odstranění (CRUD), který vygenerování MVC automaticky vytvoří v řadičích a zobrazeních.
Poznámka:
Běžným postupem je implementovat vzor úložiště, abyste vytvořili abstraktní vrstvu mezi kontrolerem a vrstvou přístupu k datům. Aby byly tyto kurzy jednoduché a zaměřené na výuku samotného EF 6, nepoužívají úložiště. Informace o tom, jak implementovat úložiště, najdete v mapě obsahu ASP.NET Data Accessu.
Tady jsou příklady webových stránek, které vytvoříte:
V tomto kurzu se naučíte:
- Vytvoření stránky Podrobností
- Aktualizace stránky Vytvořit
- Aktualizace metody HttpPost Edit
- Aktualizace stránky Odstranit
- Zavření připojení k databázi
- Zpracování transakcí
Požadavky
Vytvoření stránky Podrobností
Vygenerovaný kód pro stránku Students Index
opustil Enrollments
vlastnost, protože tato vlastnost obsahuje kolekci. Na Details
stránce zobrazíte obsah kolekce v tabulce HTML.
V Controllers\StudentController.cs metoda akce pro Details
zobrazení používá metodu Find k načtení jedné Student
entity.
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);
}
Hodnota klíče se předá metodě jako id
parametr a pochází ze směrovacích dat v hypertextovém odkazu Podrobnosti na stránce Index.
Tip: Směrování dat
Směrovací data jsou data, která pořadač modelů našel v segmentu adresy URL zadaném ve směrovací tabulce. Například výchozí trasa určuje controller
, action
a id
segmenty:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
V následující adrese URL se výchozí trasy mapují Instructor
jako controller
směrovací hodnoty , Index
jako action
a 1 jako id
hodnoty směrovacích dat.
http://localhost:1230/Instructor/Index/1?courseID=2021
?courseID=2021
je hodnota řetězce dotazu. Pořadač modelů bude fungovat také v případě, že předáte id
hodnotu řetězce dotazu:
http://localhost:1230/Instructor/Index?id=1&CourseID=2021
Adresy URL se vytvářejí příkazy ActionLink
v zobrazení Razor. V následujícím kódu id
se parametr shoduje s výchozí trasou, takže id
se přidá do směrovacích dat.
@Html.ActionLink("Select", "Index", new { id = item.PersonID })
V následujícím kódu courseID
neodpovídá parametru ve výchozí trase, takže se přidá jako řetězec dotazu.
@Html.ActionLink("Select", "Index", new { courseID = item.CourseID })
Vytvoření stránky Podrobnosti
Otevřete Views\Student\Details.cshtml.
Každé pole se zobrazí pomocí pomocné rutiny
DisplayFor
, jak je znázorněno v následujícím příkladu:<dt> @Html.DisplayNameFor(model => model.LastName) </dt> <dd> @Html.DisplayFor(model => model.LastName) </dd>
EnrollmentDate
Za pole a bezprostředně před uzavírací</dl>
značku přidejte zvýrazněný kód, který zobrazí seznam registrací, jak je znázorněno v následujícím příkladu:<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>
Pokud je odsazení kódu po vložení kódu chybné, stiskněte Ctrl+K, Ctrl+D a naformátujte ho.
Tento kód prochází entitami v
Enrollments
navigační vlastnosti. Pro každouEnrollment
entitu ve vlastnosti se zobrazí název kurzu a známka. Název kurzu se načte zCourse
entity, která je uložená vCourse
navigační vlastnostiEnrollments
entity. Všechna tato data se z databáze načítají automaticky, když je to potřeba. Jinými slovy, používáte opožděné načítání. Nezadali jste dychtivé načítání proCourses
navigační vlastnost, takže registrace nebyly načteny ve stejném dotazu, který získal studenty. Místo toho se při prvním pokusuEnrollments
o přístup k navigační vlastnosti odešle do databáze nový dotaz, který načte data. Další informace o opožděné načítání a dychtivé načítání si můžete přečíst v kurzu Čtení souvisejících dat dále v této sérii.Otevřete stránku Podrobnosti spuštěním programu (Ctrl+F5), výběrem karty Studenti a následným kliknutím na odkaz Podrobnosti pro Alexander Carson. (Pokud stisknete Při otevření souboru Details.cshtml se zobrazí ctrl+F5, zobrazí se chyba HTTP 400. Důvodem je to, že se Visual Studio pokusí spustit stránku Podrobností, ale nebyl dosažen z odkazu, který určuje studenta, který se má zobrazit. Pokud k tomu dojde, odeberte z adresy URL položku Student/Details a zkuste to znovu nebo zavřete prohlížeč, klikněte pravým tlačítkem myši na projekt a klikněte na Zobrazit>v prohlížeči.)
Zobrazí se seznam kurzů a známek pro vybraného studenta.
Zavřete prohlížeč.
Aktualizace stránky Vytvořit
V Controllers\StudentController.cs nahraďte metodu HttpPostAttribute
Create
akce následujícím kódem. Tento kód přidátry-catch
blok a odebere z atributu BindAttribute pro vygenerovanouID
metodu:[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); }
Tento kód přidá entitu
Student
vytvořenou pořadačem modelu ASP.NET MVC doStudents
sady entit a uloží změny do databáze. Pořadač modelů odkazuje na funkci ASP.NET MVC, která usnadňuje práci s daty odeslanými formulářem. Pořadač modelu převede publikované hodnoty formuláře na typy CLR a předá je metodě akce v parametrech. V tomto případě pořadač modelů vytvoříStudent
instanci entity za vás pomocí hodnot vlastností zForm
kolekce.Odebrali
ID
jste z atributu Bind, protožeID
je hodnota primárního klíče, kterou SQL Server nastaví automaticky při vložení řádku. Vstup od uživatele nenastavíID
hodnotu.Upozornění zabezpečení – Atribut
ValidateAntiForgeryToken
pomáhá předcházet útokům typu útok na negery mezi weby . Vyžaduje odpovídajícíHtml.AntiForgeryToken()
příkaz v zobrazení, který uvidíte později.Atribut
Bind
je jedním ze způsobů, jak chránit před nadměrným publikováním ve scénářích vytváření. Předpokládejme například, že entitaStudent
obsahujeSecret
vlastnost, kterou nechcete, aby tato webová stránka byla nastavena.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; } }
I když nemáte
Secret
pole na webové stránce, mohl by hacker použít nástroj, jako je fiddler, nebo napsat nějaký JavaScript a publikovatSecret
hodnotu formuláře. BindAttribute Bez omezení atributů pole, která binder modelu používá při vytvářeníStudent
instance, by pořadač modelu vyzvedá tutoSecret
hodnotu formuláře a použil ho k vytvořeníStudent
instance entity. Pak by se ve vaší databázi aktualizovala jakákoli hodnota, kterou hacker zadal proSecret
pole formuláře. Následující obrázek znázorňuje nástroj fiddler, který přidáváSecret
pole (s hodnotou OverPost) do odeslaných hodnot formuláře.Hodnota OverPost by se pak úspěšně přidala do
Secret
vlastnosti vloženého řádku, i když jste nikdy nechtěli, aby webová stránka mohla tuto vlastnost nastavit.Nejlepší je použít
Include
parametr s atributemBind
k explicitní výpisu polí. Parametr je také možné použítExclude
k blokování polí, která chcete vyloučit.Include
Důvodem je bezpečnější, že když do entity přidáte novou vlastnost, nebude nové pole automaticky chráněno seznamemExclude
.Pokud chcete zabránit nadměrnému umístění ve scénářích úprav, je nejprve čtením entity z databáze a následným voláním
TryUpdateModel
a předáním explicitního seznamu povolených vlastností. To je metoda použitá v těchto kurzech.Alternativní způsob, jak zabránit nadměrnému příspěvku, který upřednostňuje mnoho vývojářů, je použít modely zobrazení místo tříd entit s vazbou modelu. Do modelu zobrazení zahrňte pouze vlastnosti, které chcete aktualizovat. Po dokončení pořadače modelu MVC zkopírujte vlastnosti modelu zobrazení do instance entity, volitelně pomocí nástroje, jako je automapper. Použijte databázi. Položka instance entity, která nastaví její stav na Beze změny, a pak vlastnost("PropertyName"). IsModified to true on each entity property that is included in the view model. Tato metoda funguje ve scénářích pro úpravy i vytváření.
Kromě atributu
Bind
try-catch
je blok jedinou změnou, kterou jste provedli v kódu vygenerovaného uživatelského rozhraní. Pokud je při ukládání změn zachycena výjimka odvozená od DataException změn, zobrazí se obecná chybová zpráva. DataException Výjimky jsou někdy způsobeny něčím, co není externí aplikací, a ne programovací chybou, takže uživateli doporučujeme zkusit to znovu. I když není v této ukázce implementováno, aplikace v produkční kvalitě zaznamená výjimku. Další informace najdete v části Protokol pro přehled v tématu Monitorování a telemetrie (vytváření reálných cloudových aplikací pomocí Azure).Kód v Views\Student\Create.cshtml je podobný tomu, co jste viděli v Details.cshtml, s tím rozdílem, že
EditorFor
aValidationMessageFor
pomocné rutiny se používají pro každé pole místoDisplayFor
. Tady je příslušný kód:<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 také obsahuje
@Html.AntiForgeryToken()
, který funguje s atributemValidateAntiForgeryToken
v kontroleru, aby se zabránilo útokům typu forgery mezi weby .V souboru Create.cshtml nejsou vyžadovány žádné změny.
Spusťte stránku spuštěním programu, výběrem karty Studenti a následným kliknutím na Vytvořit nový.
Zadejte jména a neplatné datum a kliknutím na Vytvořit zobrazíte chybovou zprávu.
Toto je ověřování na straně serveru, které získáte ve výchozím nastavení. V pozdějším kurzu se dozvíte, jak přidat atributy, které generují kód pro ověřování na straně klienta. Následující zvýrazněný kód ukazuje kontrolu ověření modelu v metodě Create .
if (ModelState.IsValid) { db.Students.Add(student); db.SaveChanges(); return RedirectToAction("Index"); }
Změňte datum na platnou hodnotu a kliknutím na Vytvořit zobrazte nového studenta na stránce Rejstřík .
Zavřete prohlížeč.
Aktualizace metody HttpPost Edit
Nahraďte metodu HttpPostAttribute
Edit
akce následujícím kódem:[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); }
Poznámka:
V Controllers\StudentController.cs
HttpGet Edit
metoda (bez atributuHttpPost
) používáFind
metodu k načtení vybranéStudent
entity, jak jste viděliDetails
v metodě. Tuto metodu nemusíte měnit.Tyto změny implementují osvědčený postup zabezpečení, aby se zabránilo nadměrnému umístění, vygeneroval
Bind
scaffolder atribut a přidal entitu vytvořenou pořadačem modelu do sady entit s příznakem Změněno. Tento kód se už nedoporučuje, protožeBind
atribut vymaže všechna předem existující data v polích, která nejsou uvedená v parametruInclude
. V budoucnu se scaffolder kontroleru MVC aktualizuje, aby negenerovalBind
atributy pro metody Edit.Nový kód přečte existující entitu a volání TryUpdateModel pro aktualizaci polí ze vstupu uživatele v publikovaných datech formuláře. Automatické sledování změn Entity Framework nastaví u entity příznak EntityState.Modified . Když se volá metoda SaveChanges , příznak způsobí, Modified že Entity Framework vytvoří příkazy SQL aktualizovat řádek databáze. Konflikty souběžnosti se ignorují a všechny sloupce řádku databáze se aktualizují, včetně sloupců, které uživatel nezměnil. (V pozdějším kurzu se dozvíte, jak zpracovat konflikty souběžnosti a jestli chcete aktualizovat pouze jednotlivá pole v databázi, můžete entitu nastavit na EntityState.Beze změny a nastavení jednotlivých polí na EntityState.Modified.)
Aby se zabránilo přesunutí, pole, která chcete aktualizovat stránkou Upravit, jsou uvedená v parametrech
TryUpdateModel
. V současné době nejsou k dispozici žádná další pole, která chráníte, ale výpis polí, která má pořadač modelů svázat, zajistí, že pokud přidáte pole do datového modelu v budoucnu, budou automaticky chráněná, dokud je sem explicitně nepřidáte.V důsledku těchto změn je podpis metody HttpPost Edit metoda stejný jako HttpGet edit metoda; proto jste přejmenovali metodu EditPost.
Tip
Stavy entit a metody Attach a SaveChanges
Kontext databáze sleduje, jestli se entity v paměti synchronizují s odpovídajícími řádky v databázi a tyto informace určují, co se stane při volání
SaveChanges
metody. Když například předáte novou entitu metodě Add , stav této entity je nastaven naAdded
. Když pak zavoláte metodu SaveChanges , kontext databáze vydá příkaz SQLINSERT
.Entita může být v jednom z následujících stavů:
Added
. Entita ještě v databázi neexistuje. MetodaSaveChanges
musí vydatINSERT
příkaz.Unchanged
. Metodou není potřeba s touto entitouSaveChanges
nic dělat. Při čtení entity z databáze začne entita s tímto stavem.Modified
. Některé nebo všechny hodnoty vlastností entity byly změněny. MetodaSaveChanges
musí vydatUPDATE
příkaz.Deleted
. Entita byla označena k odstranění. MetodaSaveChanges
musí vydatDELETE
příkaz.Detached
. Entita není sledována kontextem databáze.
V desktopové aplikaci se změny stavu obvykle nastaví automaticky. V desktopovém typu aplikace přečtete entitu a provedete změny některých hodnot jeho vlastností. To způsobí, že se stav entity automaticky změní na
Modified
. Při voláníSaveChanges
Entity Framework vygeneruje příkaz SQLUPDATE
, který aktualizuje pouze skutečné vlastnosti, které jste změnili.Odpojená povaha webových aplikací neumožňuje tuto průběžnou sekvenci. DbContext, který čte entitu, je uvolněn po vykreslení stránky.
HttpPost
Edit
Když je volána metoda akce, provede se nový požadavek a máte novou instanci DbContext, takže při volání musíte ručně nastavit stav entity naModified.
Hodnotu Pak při voláníSaveChanges
Entity Framework aktualizuje všechny sloupce řádku databáze, protože kontext nemá způsob, jak zjistit, které vlastnosti jste změnili.Pokud chcete, aby příkaz SQL
Update
aktualizoval pouze pole, která uživatel skutečně změnil, můžete původní hodnoty uložit nějakým způsobem (například skrytá pole), aby byly k dispozici přiHttpPost
Edit
volání metody. Pak můžete vytvořit entituStudent
pomocí původních hodnot, volat metoduAttach
s původní verzí entity, aktualizovat hodnoty entity na nové hodnoty a potom volatSaveChanges.
Další informace naleznete v tématu Stavy entit a SaveChanges a Místní data.Kód HTML a Razor v Views\Student\Edit.cshtml se podobá kódu, který jste viděli v souboru Create.cshtml a nejsou potřeba žádné změny.
Spusťte stránku spuštěním programu, výběrem karty Studenti a následným kliknutím na hypertextový odkaz Upravit .
Změňte některá data a klikněte na Uložit. Změněná data se zobrazí na stránce Index.
Zavřete prohlížeč.
Aktualizace stránky Odstranit
V Controllers\StudentController.cs kód šablony pro metodu HttpGetAttribute Delete
používá metodu Find
k načtení vybrané Student
entity, jak jste viděli v metodách Details
a Edit
metodách. Pokud ale chcete implementovat vlastní chybovou zprávu v případě selhání volání SaveChanges
, přidáte do této metody některé funkce a odpovídající zobrazení.
Jak jste viděli o operacích aktualizace a vytváření, operace odstranění vyžadují dvě metody akcí. Metoda, která je volána v reakci na požadavek GET, zobrazí zobrazení, které uživateli umožní schválit nebo zrušit operaci odstranění. Pokud ho uživatel schválí, vytvoří se žádost POST. V takovém případě HttpPost
Delete
se volá metoda a pak tato metoda skutečně provede operaci odstranění.
Do metody přidáte try-catch
blok HttpPostAttribute Delete
pro zpracování všech chyb, ke kterým může dojít při aktualizaci databáze. Pokud dojde k chybě, HttpPostAttribute Delete
metoda volá metodu HttpGetAttribute Delete
a předá jí parametr, který indikuje, že došlo k chybě. Metoda HttpGetAttribute Delete
pak znovu zobrazí potvrzovací stránku spolu s chybovou zprávou, která uživateli dává příležitost zrušit nebo zkusit znovu.
Nahraďte metodu HttpGetAttribute
Delete
akce následujícím kódem, který spravuje hlášení chyb: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); }
Tento kód přijímá volitelný parametr , který označuje, zda byla metoda volána po selhání uložení změn. Tento parametr je
false
v případě, žeHttpGet
Delete
metoda je volána bez předchozího selhání. Když je volána metodouHttpPost
Delete
v reakci na chybu aktualizace databáze, parametr jetrue
a do zobrazení se předá chybová zpráva.Nahraďte metodu HttpPostAttribute
Delete
akce (pojmenovanouDeleteConfirmed
) následujícím kódem, který provede skutečnou operaci odstranění a zachytí všechny chyby aktualizace databáze.[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"); }
Tento kód načte vybranou entitu a potom zavolá metodu Remove , která nastaví stav entity na
Deleted
. PřiSaveChanges
volání se vygeneruje příkaz SQLDELETE
. Změnili jste také název metody akce zDeleteConfirmed
naDelete
. Vygenerovaný kód pojmenovaný metodouHttpPost
Delete
DeleteConfirmed
HttpPost
, který metodě poskytne jedinečný podpis. (CLR vyžaduje přetížené metody, aby měly různé parametry metody.) Teď, když jsou podpisy jedinečné, můžete držet konvence MVC a použít stejný název proHttpPost
metody aHttpGet
metody delete.Pokud je zvýšení výkonu ve vysokoobsáhové aplikaci prioritou, můžete se vyhnout zbytečnému dotazu SQL k načtení řádku tak, že nahradíte řádky kódu, které volají
Find
tytoRemove
metody, následujícím kódem:Student studentToDelete = new Student() { ID = id }; db.Entry(studentToDelete).State = EntityState.Deleted;
Tento kód vytvoří
Student
instanci entity pouze pomocí hodnoty primárního klíče a pak nastaví stav entity naDeleted
. To je vše, co Entity Framework potřebuje k odstranění entity.Jak je uvedeno,
HttpGet
Delete
metoda neodstraní data. Provedení operace odstranění v reakci na požadavek GET (nebo za tímto účelem, provedení jakékoli operace úprav, vytvoření operace nebo jakékoli jiné operace, která mění data) vytváří bezpečnostní riziko.V zobrazeních\Student\Delete.cshtml přidejte mezi nadpis a nadpis chybovou
h3
zprávuh2
, jak je znázorněno v následujícím příkladu:<h2>Delete</h2> <p class="error">@ViewBag.ErrorMessage</p> <h3>Are you sure you want to delete this?</h3>
Spusťte stránku tak, že spustíte program, vyberete kartu Studenti a potom kliknete na hypertextový odkaz Odstranit .
Na stránce s informací, že opravdu chcete odstranit, zvolte Odstranit.
Stránka Rejstřík se zobrazí bez odstraněného studenta. (V kurzu souběžnosti uvidíte příklad kódu zpracování chyb v akci.)
Zavření připojení k databázi
Pokud chcete zavřít připojení k databázi a uvolnit prostředky, které uchovávají co nejdříve, odstraňte instanci kontextu, jakmile s ní budete hotovi. Proto kód vygenerovaný vygenerovaný kód poskytuje metodu Dispose na konci StudentController
třídy v StudentController.cs, jak je znázorněno v následujícím příkladu:
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
Základní Controller
třída již implementuje IDisposable
rozhraní, takže tento kód jednoduše přidá přepsání metody Dispose(bool)
explicitně odstranit kontextovou instanci.
Zpracování transakcí
Ve výchozím nastavení Entity Framework implicitně implementuje transakce. Ve scénářích, ve kterých provedete změny v několika řádcích nebo tabulkách a potom zavoláte SaveChanges
, entity Framework automaticky zajistí, aby všechny vaše změny proběhly úspěšně nebo všechny selžou. Pokud se některé změny dokončí nejprve a dojde k chybě, tyto změny se automaticky vrátí zpět. Scénáře, ve kterých potřebujete větší kontrolu – například pokud chcete zahrnout operace provedené mimo Entity Framework v transakci – viz Práce s transakcemi.
Získání kódu
Další materiály
Teď máte úplnou sadu stránek, které pro entity provádějí jednoduché operace Student
CRUD. Použili jste pomocné rutiny MVC k vygenerování prvků uživatelského rozhraní pro datová pole. Další informace o pomocných rutinách MVC najdete v tématu Vykreslení formuláře pomocí pomocných rutin HTML (článek je pro MVC 3, ale stále je relevantní pro MVC 5).
Odkazy na další prostředky EF 6 najdete v tématu ASP.NET Přístup k datům – doporučené zdroje informací.
Další kroky
V tomto kurzu se naučíte:
- Vytvoření stránky Podrobností
- Aktualizace stránky Vytvořit
- Aktualizace metody HttpPost Edit
- Aktualizace stránky Odstranit
- Uzavřená připojení k databázi
- Zpracovávané transakce
V dalším článku se dozvíte, jak do projektu přidat řazení, filtrování a stránkování.