Zarábaj až 6 000 € mesačne! Akreditované rekvalifikačné kurzy od 0 €. Viac informácií.
Hľadáme nové posily do ITnetwork tímu. Pozri sa na voľné pozície a pridaj sa k najagilnejšej firme na trhu - Viac informácií.

10. diel - Scaffolding a Entity Framework v ASP.NET Core MVC

V minulej lekcii, Úprava layotu a obsahových stránok v ASP.NET Core MVC , sme dokončili úpravu štruktúry východiskovej MVC šablóny a obsahových stránok tak, aby vyzerali ako osobný blog.

Dnešný ASP.NET Core tutoriál bude nabitý najmodernejšími technológiami, pomocou ktorých vytvoríme behom okamihu administráciu článkov na našom blogu. Budeme tak môcť na ňom písať, ukladať a prezentovať vlastné články.

Budeme pokračovať s projektom z lekcie Úprava layotu a obsahových stránok v ASP.NET Core MVC.

Scaffolding

Webové frameworky sú koncipované tak, aby čo najviac zjednodušili prácu programátora a najmä zredukovali množstvo kódu, ktoré musí napísať. Hoci sa im to darí, tak stále existujú situácie, kde je určité množstvo stereotypného kódu potrebné a neexistuje spôsob, akým by ho framework mohol nahradiť.

Chystáme sa programovať administráciu článkov na webe a preto budeme potrebovať:

  • kontrolér,
  • model článku,
  • databázu na uloženie článkov,
  • pohľady pre výpis, editácia, pridanie, odstránenie a detail článkov.
Tieto súčasti aplikácie jednoducho musia obsahovať a nezáleží na tom, v akom geniálnom jazyku ju programujeme. Nemusí ich však stereotypne písať programátor, ale môže ich za nás vygenerovať IDE. Tomuto princípu sa hovorí scaffolding (najlepší preklad je asi lešenie, kostra). Visual Studio nám jednoducho predgeneruje databázu, kontrolér a pohľady. Získame tak kostru so základnou funkčnosťou, ktorú iba upravíme.
Scaffolding v ASP.NET Core MVC - Základy ASP.NET Core MVC - Základy ASP.NET Core MVC

Uloženie dát

Nami napísané články budeme musieť niekam ukladať, budeme teda potrebovať nejaké úložisko dát. K tomu nám poslúži relačná databáza. Tento pojem označuje databázu založenú na tabuľkách. Každá tabuľka obsahuje položky jedného typu. Môžeme mať teda tabuľku Uzivatele, ďalšiu tabuľku Clanky a ďalšie napríklad Komentare.

Databázovú tabuľku si môžeme predstaviť napríklad ako tabuľku v Exceli. Tabuľka Uzivatele by mohla vyzerať asi takto:

Meno Priezvisko Dátum narodenia Počet článkov
Ján Novák 11.3.1984 17
Tomáš Márny 1.2.1989 6
Jozef Nový 20.12.1972 9
Michaela Sláviková 14.8.1990 1
Položky (konkrétne tu užívateľa) ukladáme na jednotlivé riadky, stĺpce potom označujú atribúty (vlastnosti, ak chcete), ktoré položky majú. Každý stĺpec má pevne stanovený dátový typ (číslo, znak, krátky text, dlhý text...) a môže obsahovať hodnoty iba tohto typu.

Pokiaľ chceme s relačnou databázou rozumne pracovať, každý riadok v tabuľke by mal byť opatrený unikátnym identifikátorom. U užívateľov by to mohlo byť potrebné rodné číslo, oveľa častejšie sa však používajú identifikátory umelé a to tak, že užívateľov jednoducho očíslujeme. V relačných databázach sa tento identifikátor tiež nazýva primárny kľúč.

MS-SQL databázy

V tomto kurze využijeme relačnú databázu typu MS-SQL. Jedná sa o veľmi sofistikovaný a odladený nástroj, ktorý za nás rieši množstvo problémov a zároveň je extrémne jednoduchý na použitie. S databázou komunikujeme jazykom SQL, ktorým sú v podstate ľudsky zrozumiteľné vety. Nad týmto jazykom vzniklo mnoho nadstavieb a niekedy sa už dokonca s SQL vôbec nestretneme. To bude práve aj náš prípad. S relačnou databázou totiž budeme pracovať pomocou technológie Entity Framework Core.

V našej aplikácii využijeme iba odľahčenú verziu MS-SQL databázy označovanú ako LocalDB. Táto databáza sa najčastejšie používa buď pri vývoji aplikácie, a vo finálnej verzii je nahradená plnohodnotnou databázou, alebo niekedy aj ako lokálne úložisko dát.

V druhom prípade sa však skôr volí databáza SQLite.

Entity Framework Core

Entity Framework Core je tzv. O bjektovo R elačné M apper (ORM) pre prístup k databázam. Databázové tabuľky sa priamo mapujú na C# triedy, v kóde pracujeme len s objektmi a framework sám na pozadí generuje SQL kód. S jazykom SQL vôbec neprídeme do styku a naša aplikácia je 100% objektová.

Prístup k databáze je v Entity Framework Core realizovaný cez tzv. model. Ide o popis štruktúry databázy vo forme C# tried, ktorý sa skladá najmä z entít a databázového kontextu.

Pod entitou si môžeme jednoducho predstaviť tabuľku databázy, ktorú v C# reprezentujeme triedou. Databázový kontext potom predstavuje a definuje:

  • samotné prepojenie s databázou,
  • všetky tabuľky databázy (entity) a
  • väzby medzi nimi.
Všetka komunikácia s databázou prebieha cez tento databázový kontext.

Code First a Database First prístupy

S Entity Frameworkom je možné pracovať dvoma spôsobmi. Môžeme vytvoriť C# triedu (entitu) a Entity Framework Core nám podľa nej automaticky vygeneruje databázovú tabuľku a potrebný databázový kontext. Tomuto prístupu sa hovorí Code First.

Druhý spôsob spočíva v založení databázy, z ktorej nám Entity Framework vygeneruje entity a databázový kontext. Tento prístup sa volá Database First.

Keďže vytvoriť triedu je oveľa jednoduchšie ako vytvoriť databázu, zvolíme pre tento tutoriál prístup Code First. Aj v praxi sa jedná o častejšiu voľbu.

Podrobne sa technológia Entity Framework Core rozoberá buď v samostatnom kurze tu na sieti, alebo prípadne v kurze tvorby webového API, v ktorom si presne ukazujeme, ako Entity Framework Core manuálne napojiť na ASP.NET Core aplikáciu.

Model databázy

Čo sa týka modelu databázy, tak tu nám bude stačiť vytvoriť iba entitu článku, databázový kontext totiž už máme v projekte vygenerovaný. Ide o triedu ApplicationDbContext v priečinku Data/. Táto trieda nám bola vygenerovaná už počas zakladania projektu, pretože sme zaškrtli možnosť Individual Accounts na podporu autentizácie v našej aplikácii. Účty užívateľov našej aplikácie sa totiž budú ukladať taktiež do databázy. V tomto kontexte sú zatiaľ zahrnuté iba tabuľky pre používateľské účty a roly.

Entita Article

Pretože Entity Framework Core používa určité konvencie a prevádza názvy tried do množného čísla, budeme aplikáciu písať anglicky, aby názvy neboli skomolené. Do zložky Models/ si teda pridajme novú triedu Article. Bude sa jednať o našu entitu článku, na základe ktorej sa vygeneruje tabuľka v databáze. Vlastnosti entity budú predstavovať jednotlivé stĺpce databázovej tabuľky.

Trieda bude vyzerať takto:

public class Article
{
    public int Id { get; set; }
    public string Content { get; set; } = "";
    public string Title { get; set; } = "";
    public string Description { get; set; } = "";
}

Máme tu niekoľko vlastností, konkrétne:

  • Id - unikátny identifikátor článku,
  • Content - obsah článku,
  • Title - titulok článku,
  • Description - popis článku.
Id musí mať každá entita. Až z kódu vygenerujeme tabuľky, tak sa stane jej primárnym kľúčom, ktorý bude články jednoznačne odlišovať aj keby mali napríklad rovnaký titulok.

Od Visual Studio 2022 sú všetky projekty automaticky generované s povolenou funkciou nullovateľných referenčných typov (funkcia pridaná v C# 8.0). Táto funkcia nám umožňuje nastaviť hodnotu null iba atribútom alebo vlastnostiam, ktoré majú definíciu typu označenú operátorom ?, a to aj v prípade že sa jedná o referenčný dátový typ. Každý atribút alebo vlastnosť referenčného dátového typu tak musí mať pri vytváraní objektu nastavenú nejakú východiskovú hodnotu inú ako null, pokiaľ nie je označený ako nullovateľný operátorom ?. Preto našim vlastnostiam nastavujeme ako predvolenú hodnotu prázdny reťazec.

Rebuild

Aby vedel Entity Framework Core databázu z triedy Article vygenerovať, musíme projekt s touto triedou najprv zostaviť (vykonať rebuild). To dosiahneme kliknutím pravým na projekt v Solution Explorer a výberom možnosti Rebuild. Trieda sa tým skompiluje:

Rebuild projektu v ASP.NET Core MVC - Základy ASP.NET Core MVC - Základy ASP.NET Core MVC

Kontrolér ArticlesController

Začneme tvorbou spomínaného kontroléra pre správu článkov. Pridáme si ho do zložky Controllers/ kliknutím pravým tlačidlom na danú zložku a voľbou AddController.... Zobrazí sa nám dialóg s výberom scaffoldingu, kde zvolíme MVC Controller with views, using Entity Framework:

Scaffolding controller v ASP.NET Core MVC - Základy ASP.NET Core MVC - Základy ASP.NET Core MVC

Ako model zvolíme našu triedu Article a ako dátový kontext vyberieme už existujúci kontext ApplicationDbContext. Názov kontroléra ponecháme predvolený ArticlesController a dialóg potvrdíme:

Scaffolded controller v ASP.NET Core MVC - Základy ASP.NET Core MVC - Základy ASP.NET Core MVC

Všimnime si, že môžeme nastaviť, či chceme používať layout a niekoľko ďalších vecí.

Čo sa vygenerovalo

Iba týmto jedným krokom sa nám do projektu doinštalovali všetky potrebné NuGet balíčky s Entity Framework Core a vygenerovali alebo rozšírili sa zostávajúce triedy modelu databázy.

Ďalej nám bol vygenerovaný samotný kontrolér ArticlesController s niekoľkými akciami. Nájdeme tu akcie:

  • Index() - výpis všetkých článkov,
  • Details() - výpis jedného článku,
  • Create() - vytvorenie článku,
  • Edit() - editácia článku,
  • Delete() - odstránenie článku.
Keď sa pozrieme do zložky Views/, nájdeme tu zložku Articles/ av nej päť pohľadov pre tieto akcie.

Migrácia

Síce už máme vygenerovaný celý databázový model, ale zatiaľ v databáze neexistuje tabuľka pre našu entitu Article a dokonca ani samotná databáza. Aby databáza zodpovedala našim modelom, musíme na nej vykonávať tzv. migrácie. Ide o triedy popisujúce, ako sa má databáza alebo jej tabuľky vygenerovať.

Vo Visual Studio vyberieme v hornom menu ToolsNuGet Package ManagerPackage Manager Console. V dolnej časti okna sa nám otvorí konzola, do ktorej zadáme príkaz Add-Migration pre vygenerovanie migrácie:

Add-Migration ArticleMigration

ArticleMigration je názov našej migrácie, môžeme zadať aj akýkoľvek iný. Potvrdíme klávesom Enter. Po chvíľke sa nám v zložke Data/Migrations/ vygeneruje nová trieda ArticleMigration predstavujúca danú migráciu.

Akonáhle migráciu vytvoríme, musíme ju na databázu aplikovať. To vykonáme príkazom Update-Database:

Pridanie migrácie ArticleMigration vo Visual Studio - Základy ASP.NET Core MVC - Základy ASP.NET Core MVC

Kedykoľvek rozšírime databázový model o novú triedu alebo nejakú už existujúcu triedu odstránime alebo zmeníme (napr. do neho pridáme nejakú vlastnosť, nejakú odstránime a pod.), vykonáme tento postup. Visual Studio za nás aktualizuje databázu, aby v nej boli všetky zmeny premietnuté.

Testovanie

Spustíme aplikáciu a prejdeme na odkaz Články:

Zoznam článkov v ASP.NET Core MVC - Základy ASP.NET Core MVC - Základy ASP.NET Core MVC

Vidíme, že administrácia článkov sa vygenerovala automaticky a je plne funkčná. Nejedná sa síce zatiaľ o nejaký skvost, v budúcich lekciách to však hravo napravíme. Môžeme si skúsiť pridať nejaký testovací článok odkazom Create New:

Pridanie nového článku v ASP.NET Core MVC - Základy ASP.NET Core MVC - Základy ASP.NET Core MVC

Zobrazí sa nám v zozname článkov:

Zoznam článkov v ASP.NET Core MVC - Základy ASP.NET Core MVC - Základy ASP.NET Core MVC

A môžeme si ho tiež otvoriť pomocou odkazu Details:

Detail článku v ASP.NET Core MVC - Základy ASP.NET Core MVC - Základy ASP.NET Core MVC

Získanie článku z databázy

Všimnime si URL adresy:

http://localhost:44311/Articles/Details/1

Prvý segment cesty označuje názov kontroléra ArticlesController, ktorý sa má spustiť. Druhým segmentom je názov jeho akcie Details().

O tomto mechanizme, ktorý prevádza cestu URL adresy na volanie metód kontroléra (rútovania) sme si už hovorili v predchádzajúcich lekciách. Jeho nastavenia môžeme meniť v súbore Program.cs.

V predchádzajúcich aplikáciách sme mali v kontroléri HomeController vždy len jednu akciu Index() a tá sa spustí automaticky, aj keď žiadnu cestu neuvedieme. V súbore Program.cs totiž máme nastavené východiskové smerovanie na akciu Index() kontroléra HomeController:

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

Ďalšie segmenty v ceste sú parametre danej akcie v kontroléri, tu sa jedná o Id článku, ktorý zobrazujeme. Zo vzoru cesty môžeme vyčítať, že takýto parameter je nepovinný (znak otáznika ?) a že sa akciu odovzdáva skrz parameter metódy s názvom id.

Kontrolér ArticlesController

Akcia Details() v kontroléri ArticlesController vyzerá takto:

// GET: Articles/Details/5
public async Task<IActionResult> Details(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    var article = await _context.Article
        .SingleOrDefaultAsync(m => m.Id == id);
    if (article == null)
    {
        return NotFound();
    }

    return View(article);
}

Naozaj vidíme, že nullovateľný parameter id je zapísaný ako obyčajný parameter metódy. V prípade, že parameter nie je zadaný alebo článok nie je nájdený, je vrátená odpoveď s chybou.

Získanie článku z databázy má na svedomí len tento riadok:

var article = await _context.Article.SingleOrDefaultAsync(m => m.Id == id);

Triedny atribút _context obsahuje inštanciu databázového kontextu ApplicationDbContext, v ktorom je tabuľka s článkami reprezentovaná vlastnosťou Article. Z tejto tabuľky sa jeden záznam získa jednoducho zavolaním metódy SingleOrDefaultAsync(). Pokiaľ ste Entity Framework Core nepoznali, tak ho teraz asi budete milovať :)

Asynchrónne akcie

Na tejto akcii zároveň vidíme, že akcie kontroléra môžeme pokojne zapisovať aj ako tzv. asynchrónne metódy, pokiaľ to potrebujeme. ASP.NET Core si s tým poradí.

Ide o metódy, ktoré nevracajú svoju hodnotu ihneď, ale až po nejakom časovom intervale. Medzitým program na návratovú hodnotu volanej metódy nečaká, ale pokračuje ďalej vo vykonávaní kódu. Takouto metódou je práve metóda SingleOrDefaultAsync(), ktorá vracia svoju hodnotu až potom, čo ju získa z databázy.

Kód akcie nasledujúci po volaní metódy SingleOrDefaultAsync() smie byť vykonaný až vo chvíli, keď je k dispozícii návratová hodnota tejto metódy. Na návratovú hodnotu je teda potrebné čakať. Preto sa metóda SingleOrDefaultAsync() volá s kľúčovým slovom await. Tým sa zaistí čakanie na návratovú hodnotu a vykonávanie akcie sa pozdrží. Výhodou asynchrónnych metód je, že procesor môže v priebehu čakania vykonávať akýkoľvek iný kód a efektívnejšie tak pracovať so svojím časom.

Aby sa v akcii Details() mohla volať asynchrónna metóda s kľúčovým slovom await, tak musí byť sama asynchrónnou metódou. To sa dosiahne označením metódy kľúčovým slovom async.

Viac o tejto téme sa dočítate v kurze Paralelné programovanie a viacvláknové aplikácie v C# .NET.

Databáza je uložená v lokálnom súbore, ale nie v priečinku projektu, ale vo vašej používateľskej zložke v C:\Users\<vaše jméno>. Môžete sa do nej pozrieť, súbor s databázou má príponu .mdf. Toto tiež znamená, že pokiaľ vám niečo nepôjde a budete si chcieť dnes alebo kedykoľvek nabudúce stiahnuť hotové riešenie pod článkom, databáza v ňom nebude a projekt nebude fungovať. Po stiahnutí projektu je nutné vygenerovať databázu príkazom Update-Database v Package Manager Console, čím sa prázdna databáza pre príslušný projekt vytvorí. Potom bude stiahnutý projekt ešte len fungovať.

V nasledujúcom cvičení, Riešené úlohy k 8.-10. lekciu frameworku ASP.NET Core MVC, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 403x (4.29 MB)
Aplikácia je vrátane zdrojových kódov v jazyku C#

 

Predchádzajúci článok
Úprava layotu a obsahových stránok v ASP.NET Core MVC
Všetky články v sekcii
Základy ASP.NET Core MVC
Preskočiť článok
(neodporúčame)
Riešené úlohy k 8.-10. lekciu frameworku ASP.NET Core MVC
Článok pre vás napísal Martin Petrovaj
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor je lenivý vymýšľať nejaký slušný podpis. Venuje sa ale prevažne C#.
Aktivity