Black Friday Black Friday
Black Friday výprodej! Až 80 % extra bodů zdarma! Více informací zde

Lekce 6 - Scaffolding a Entity Framework v ASP.NET Core MVC

C# .NET ASP.NET ASP.NET Core Základy ASP.NET Core MVC Scaffolding a Entity Framework v ASP.NET Core MVC

Unicorn College ONEbit hosting Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V minulé lekci, Úprava template MVC v ASP.NET Core, jsme si upravili předgenerovaný projekt z Visual Studia do podoby osobního blogu. Dnešní C# .NET tutoriál bude nabitý nejmodernějšími technologiemi, pomocí kterých vytvoříme během okamžiku administraci článků na blogu.

Scaffolding

Scaffolding v ASP.NET Core MVC

Webové frameworky jsou koncipované tak, aby co nejvíce zjednodušily práci programátora a zejména zredukovaly množství kódu, které musí napsat. Ačkoli se jim to daří, tak stále existují situace, kde je určité množství stereotypního kódu nutné a neexistuje způsob, jakým by ho framework mohl nahradit.

Chystáme se programovat administraci článků na webu a proto budeme potřebovat nějaký kontroler, model článku, databázovou tabulku a 5 pohledů (výpis, editace, přidání, odstranění, detail). Tyto součásti aplikace jednoduše musí obsahovat a nezáleží na tom, v jak geniálním jazyce ji programujeme. Nemusí je však stereotypně psát programátor, ale může je za nás vygenerovat IDE. Tomuto principu se říká scaffolding (nejlepší překlad je asi lešení, kostra). Visual Studio nám jednoduše předgeneruje databázi, kontroler a pohledy. Získáme tak kostru se základní funkčností, kterou pouze upravíme.

Entity framework

S databází budeme pracovat pomocí technologie Entity Framework Core, což je tzv. ORM (objektově-relační mapování). Databázové tabulky se přímo mapují na C# třídy, v kódu pracujeme jen s objekty a framework sám na pozadí generuje SQL dotazy. S jazykem MS-SQL vůbec nepřijdeme do styku a naše aplikace je 100% objektová. Ačkoli se budu snažit vše podrobně popisovat, doporučím nováčkům na poli ORM návštěvu sekce Databáze v C# .NET, kde je ORM popsané podrobněji.

Code First a Database First přístupy

S Entity Frameworkem můžeme pracovat dvěma způsoby. Můžeme vytvořit C# třídu a EF nám podle ní automaticky vygeneruje databázovou tabulku a potřebný kontext. Tomuto přístupu se říká Code First. Druhý způsob spočívá v založení databáze, ze které nám EF vygeneruje třídy a kontext. Asi vás nepřekvapí, že se druhý přístup jmenuje Database First. Jelikož vytvořit třídu je mnohem jednodušší než vytvořit databázi, zvolil jsem pro tutoriál přístup Code-First.

Vytvoření modelu

Protože Entity Framework používá určité konvence a převádí názvy tříd do množného čísla, budeme aplikaci psát anglicky, aby názvy nebyly zkomolené. Do složky Models si tedy přidejme novou třídu Article. Bude vypadat takto:

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

Třída obsahuje několik vlastností, konkrétně:

  • id
  • obsah
  • titulek
  • popisek

Můžete si k článku přidat např. ještě datum publikace a podobně. Id musí mít každá entita. Až z kódu vygenerujeme tabulky, tak se stane jejím primárním klíčem, který bude články jednoznačně odlišovat i kdyby měly třeba stejný titulek.

Rebuild

Aby uměl Entity Framework databázi vygenerovat, musíme projekt rebuildovat, jelikož ještě nebyl s touto třídou sestaven. Toho dosáhneme kliknutím pravým na projekt v Solution Exploreru a výběrem možnosti Rebuild. Třída se tím zkompiluje.

Rebuild projektu v ASP.NET Core MVC

Nyní si do složky Controllers přidáme nový kontroler. Zobrazí se nám dialog s výběrem Scaffoldingu, kde zvolíme MVC Controller with views, using Entity Framework.

Scaffolding controller v ASP.NET Core MVC

Jako model zvolíme naši třídu Article a jako datový kontext vybereme již existující kontext aplikace, ve kterém jsou uživatelé a jejich role. Jako název kontroleru ponecháme defaultní ArticlesController. Všimněte si, že můžeme i nastavit zda chceme používat layout a několik dalších věcí.

Scaffolded controler v ASP.NET Core MVC

Dialog potvrdíme.

Byl nám vygenerován ArticlesController s několika metodami (akcemi). Nalezneme zde akce:

  • Index() - Výpis všech článků
  • Details() - Výpis jednoho článku
  • Create() - Vytvoření článku
  • Edit() - Editace článku
  • Delete() - Odstranění článku

Když se podíváme do složky Views, nalezneme zde složku Articles a v ní 5 pohledů pro tyto akce.

Aplikaci nyní spustíme a přejdeme na záložku Články. Projekt vám nyní buď zobrazí chybovou hlášku nebo bude fungovat, záleží na verzi jednotlivých nástrojů.

Seznam článků v ASP.NET Core MVC

Migrace

Pokud vám stránka Články ukáže chybu, nebyla zavolána databázová migrace. V našem případě to znamená, že jsme si sice vytvořili třídu Article, ale zatím v databázi neexistuje korespondující tabulka. Aby databáze odpovídala našim modelům, musíme na ní provádět tzv. migrace. Ve Visual Studiu vyberte v horním menu Tools -> NuGet Package Manager -> Package Manager Console. V dolní části okna se vám otevře konzole. Tam zadejte příkaz:

Add-Migration Vytvoreni_Clanku

Vytvoreni_Clanku je název naší migrace, můžete zadat i jakýkoli jiný. Potvrďte klávesou Enter. Spuštění bude chvilku trvat.

Jakmile migrace vytvoříme, musíme je na databázi spustit. To provedeme příkazem:

Update-Database

Kdykoli vytvoříme nový databázový model, nějaký odstraníme nebo změníme (např. do něj přidáme nějakou vlastnost, nějakou odstraníme a pod.), provedeme tento postup. VS za nás aktualizuje databázi i kontext Entity Frameworku, aby v něm byly všechny změny promítnuté.

Pokud vám aplikace nefungovala, spusťte ji nyní znovu a přejděte na odkaz Články. Vidíme, že administrace článků se vygenerovala automaticky a je plně funkční. Můžeme si zkusit přidat nějaký testovací článek:

Přidání nového článku v ASP.NET Core MVC

Zobrazí se nám v seznamu článků:

Seznam článků v ASP.NET Core MVC

A můžeme si ho také otevřít pomocí odkazu Details:

Detail článku v ASP.NET Core MVC

Všimněte si URL adresy:

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

První parametr označuje název kontroleru, který se má spustit (ArticlesController), druhý je název jeho metody (Details()). V předchozích aplikacích jsme měli v kontroleru vždy jen jednu metodu (Index()) a ta se spustí automaticky, když žádný parametr nezadáme. Další parametry v adrese jsou parametry dané akce (metody) v kontroleru, zde se jedná o Id článku, který zobrazujeme.

O tomto mechanismu, který převádí URL adresu na volání metod kontroleru (routování) jsme si již ve zkratce řekli v předchozích lekcích. Jen pro připomenutí doplním, že jeho nastavení můžeme měnit v Startup.cs.

Metoda details v ArticlesController vypadá 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);
}

Nullovatelný parametr id je zapsán jako obyčejný parametr metody. Získání článku z databáze má na svědomí opravdu jen tento řádek:

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

Pokud jste Entity Framework neznali, tak ho nyní asi budete milovat :)

Databáze je uložená v lokálním souboru, ovšem nikoli ve složce projektu, ale ve vaší uživatelské složce v C:\Users\<vaše jméno>. Můžete se do ní podívat, soubor s databází má příponu .mdf. Toto také znamená, že pokud vám něco nepůjde a budete si chtít dnes nebo kdykoli příště stáhnout hotové řešení pod článkem, databáze v něm nebude a projekt nebude fungovat. Po stažení projektu je nutné zavolat příkazy Add-Migration Nazev_Migrace a Update-Database v Package Manager Console, čímž se vám prázdná databáze pro příslušný projekt vytvoří. Poté bude stažený projekt teprve fungovat

Zkuste si pročíst zdrojový kód dnešního řešení a zopakovat si ještě jak vše funguje. V příští lekci, Úprava administrace článků a editor v ASP.NET Core MVC, začneme scaffoldovaný kód upravovat tak, aby se články přiblížily nějaké naší představě. Projekt je jako vždy níže ke stažení.


 

Stáhnout

Staženo 25x (2.39 MB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

 

Článek pro vás napsal Martin Petrovaj
Avatar
Jak se ti líbí článek?
1 hlasů
Autor je lenivý vymýšľať nejaký slušný podpis. Venuje sa ale prevažne C#.
Aktivity (3)

 

 

Komentáře

Avatar
deli
Člen
Avatar
deli:26. září 14:24

Zial, v aplikaci vobec nie je dorobene pridavanie clankov.

http://img173.imagevenue.com/img.php?…

 
Odpovědět 26. září 14:24
Avatar
deli
Člen
Avatar
deli:26. září 14:28

Zial, v aplikaci vobec nie je dorobene pridavanie clankov.

http://www.imagevenue.com/uploadflash.php

 
Odpovědět 26. září 14:28
Avatar
Martin Petrovaj
Překladatel
Avatar
Odpovídá na deli
Martin Petrovaj:26. září 14:47

Stiahol som k článku priložený projekt a pridanie nového článku tam je. http://prntscr.com/kyy38b
Článok tiež presne opisuje postup, ako sa dostať k správnemu výsledku. Tvoj problém znie, ako keby si pri vytváraní kontroleru nezvolil možnosť "MVC Controller with views", príp. nezaškrtol "Generate Views".

Skús si to, prosím, prejsť ešte raz, poprípade skontrolovať s priloženým projektom. Je možné (aj keď nie veľmi pravdepodobné), že by sa opäť zmenili nástroje a workflow vo Visual Studiu a tieto views sa musia vygenerovať nejako inak, ale nič také som si nedávno ešte nevšimol.

Odpovědět 26. září 14:47
if (this.motto == "") { throw new NotImplementedException(); }
Avatar
Vojtěch Prchal:1. listopadu 21:02

Zdravím, bohužel mi v Chromu nejde přidávat články, jen po odstranění ValidateAntiFor­geryToken.
V ostatních prohlížečích to funguje.. Neví někdo proč v Chromu ne?

Stránka vrací Kód chyby 404

Editováno 1. listopadu 21:04
 
Odpovědět 1. listopadu 21:02
Avatar
Martin Petrovaj
Překladatel
Avatar
Odpovídá na Vojtěch Prchal
Martin Petrovaj:1. listopadu 21:12

Nie som si istý či to bude ono, ale pri ASP.NET Core 2.0 MVC robil Chrome problémy práve s Antiforgery cookie, ak sa so stránkou komunikovalo cez HTTP (HTTPS ten problém nemal).

Skús si prejsť toto vlákno, či sa nejedná o tvoj problém. Ak áno, mal by si tam nájsť rovno aj nejaké rady:
https://github.com/…/issues/6673

Odpovědět 1. listopadu 21:12
if (this.motto == "") { throw new NotImplementedException(); }
Avatar
Michal Cikryt:8. listopadu 23:49

Udělal jsem všechny kroky podle návodu (opakovaně). Při příkazu Add-Migration mi to vypíše žlutě hlášku:
"The EF Core tools version '2.1.1-rtm-30846' is older than that of the runtime '2.1.4-rtm-31024'. Update the tools for the latest features and bug fixes."
Nicméně migration se vytvoří.

Následně při příkazu "Update-Database" to na konci procesu vypíše hlášku:
ClientConnecti­onId:00000000-0000-0000-0000-000000000000
Error Number:-1983577846,St­ate:0,Class:20
(níže je červeně):
A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 50 - Local Database Runtime error occurred. Error occurred during LocalDB instance startup: SQL Server process failed to start.

Uměl by prosím někdo poradit, v čem je chyba?
Zkoušel jsem doinstalovat EntityFramework příkazem: Install-Package Microsoft.Enti­tyFrameworkCo­re.Tools -Version 2.1.4 ,ale nepomohlo to.

Updatoval jsem VS na nejnovější verzi a udělal celý projekt znovu, ale se stejným výsledkem.

Díky moc za případnou radu.

 
Odpovědět 8. listopadu 23:49
Avatar
Odpovídá na Michal Cikryt
Michal Štěpánek:9. listopadu 8:29

Podle té chyby máš problém s připojením k databázi. Zkusil bych přeinstalovat SQL Server (samozřejmě pokud máš express verzi lokální). Pokud používáš klasický MSSQL Server, tak zkontroluj konektivitu...

Odpovědět 9. listopadu 8:29
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Jan Hodic
Člen
Avatar
Jan Hodic:14. listopadu 6:39

Delal jsem migraci k tride Immobilities. Dostal jsem nasledujici chybu:

Add-Migration Immobilities
Both Entity Framework 6.x and Entity Framework Core commands are installed. The Entity Framework 6 version is executing. You can fully qualify the command to select which one to execute, 'EntityFramewor­k\Add-Migration' for EF6.x and 'EntityFramewor­kCore\Add-Migration' for EF Core.
Exception calling "SetData" with "2" argument(s): "Typ Microsoft.Visu­alStudio.Projec­tSystem.VS.Im­plementation.Pac­kage.Automati­on.OAProject v sestavení Microsoft.Visu­alStudio.Projec­tSystem.VS.Im­plementat
ion, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f­11d50a3a není označen jako serializovatelný."
At C:\Users\Hodic\­.nuget\packages\en­tityframework\6­.2.0\tools\En­tityFramework­.psm1:720 char:5

  • $domain.SetDa­ta('project', $project)
  • ~~~~~~~~~~~~~­~~~~~~~~~~~~~~~~~~~~~~~
    • CategoryInfo : NotSpecified: (:) [], MethodInvocati­onException
    • FullyQualifie­dErrorId : SerializationEx­ception

Exception calling "SetData" with "2" argument(s): "Typ Microsoft.Visu­alStudio.Projec­tSystem.VS.Im­plementation.Pac­kage.Automati­on.OAProject v sestavení Microsoft.Visu­alStudio.Projec­tSystem.VS.Im­plementat
ion, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f­11d50a3a není označen jako serializovatelný."
At C:\Users\Hodic\­.nuget\packages\en­tityframework\6­.2.0\tools\En­tityFramework­.psm1:721 char:5

  • $domain.SetDa­ta('contextPro­ject', $contextProject)
  • ~~~~~~~~~~~~~­~~~~~~~~~~~~~~~~~~~~~~~~­~~~~~~~~~~~~~
    • CategoryInfo : NotSpecified: (:) [], MethodInvocati­onException
    • FullyQualifie­dErrorId : SerializationEx­ception

Exception calling "SetData" with "2" argument(s): "Typ Microsoft.Visu­alStudio.Projec­tSystem.VS.Im­plementation.Pac­kage.Automati­on.OAProject v sestavení Microsoft.Visu­alStudio.Projec­tSystem.VS.Im­plementat
ion, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f­11d50a3a není označen jako serializovatelný."
At C:\Users\Hodic\­.nuget\packages\en­tityframework\6­.2.0\tools\En­tityFramework­.psm1:722 char:5

  • $domain.SetDa­ta('startUpPro­ject', $startUpProject)
  • ~~~~~~~~~~~~~­~~~~~~~~~~~~~~~~~~~~~~~~­~~~~~~~~~~~~~
    • CategoryInfo : NotSpecified: (:) [], MethodInvocati­onException
    • FullyQualifie­dErrorId : SerializationEx­ception

System.NullRe­ferenceExcepti­on: Odkaz na objekt není nastaven na instanci objektu.
v System.Data.En­tity.Migration­s.Extensions.Pro­jectExtension­s.GetProperty­ValueT
v System.Data.En­tity.Migration­s.MigrationsDo­mainCommand.Get­Facade(String configuration­TypeName, Boolean useContextWor­kingDirectory)
v System.Data.En­tity.Migration­s.AddMigration­Command.Execu­te(String name, Boolean force, Boolean ignoreChanges)
v System.Data.En­tity.Migration­s.AddMigration­Command.<>c__Dis­playClass2.<.ctor>b__0()
v System.Data.En­tity.Migration­s.MigrationsDo­mainCommand.E­xecute(Action command)
Odkaz na objekt není nastaven na instanci objektu.

 
Odpovědět 14. listopadu 6:39
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 8 zpráv z 8.