Lekce 3 - Generování databáze v Entity Framework Core a C# .NET
V minulé lekci, Instalace a první model v Entity Framework Core a C# .NET, jsme si založili náš první projekt s Entity Framework Core a vytvořili jednoduchý model.
V dnešním Entity Framework Core tutoriálu, a to v jazyce C# .NET, si necháme vygenerovat databázi z našeho prvního modelu.
Jak již bylo několikrát řečeno, ke komunikaci s databází budeme v Entity Framework Core využívat instanci databázového kontextu. Než si ale takovou instanci vytvoříme, tak si řekneme něco málo o její životnosti.
Životnost databázového kontextu
Životnost instance databázového kontextu začíná ve chvíli jejího
vytvoření a končí, když je na ni zavolána metoda Dispose()
.
Tato metoda ukončí spojení s databází a odebere instanci všechny zdroje.
Instance databázového kontextu jsou určeny k použití na jednu tzv.
jednotku práce.
Nepoužíváme tedy jednu instanci databázového kontextu po dobu životnosti celé aplikace.
Pod jednotkou práce si můžeme představit jednoduchou a nedělitelnou operaci nad databází. V redakčním systému by to například mohlo být:
- získání všech článků konkrétního autora z databáze,
- vložení nového článku,
- vložení více nových kategorií článků najednou,
- smazání všech článků bez autora nebo
- změna kategorií článku, kdy některé mu odebereme a jiné naopak přidáme.
Životnost instance databázového kontextu je obvykle velmi krátká. V případě webových ASP.NET Core aplikací je životnost instance typicky určena dobou nutnou pro vyřízení jednoho HTTP požadavku zaslaného na náš server.
Generování databáze
Vygenerovat databázi z našeho modelu můžeme dvěma způsoby. Buď pomocí
systému tzv. migrací, anebo pomocí metody
EnsureCreated()
. Migrace nám umožňují jednoduše aplikovat
změny modelu na databázi, aniž přijdeme o uložená data. Jedná se o
nejčastější způsob generování databáze v Entity Framework Core. Na
migrace se však zaměříme až v budoucích lekcích. V dnešní lekci
použijeme metodu EnsureCreated()
.
Metoda EnsureCreated()
Jak název napovídá, metoda EnsureCreated()
dokáže zajistit,
že je databáze vytvořena. V případě, že v době jejího zavolání není
vytvořena, metoda ji automaticky vygeneruje z modelu. Pokud databáze již
existuje, tak metoda nic neprovede, a to i v případě, kdy se její struktura
liší od našeho modelu. Nedokáže tedy zajistit synchronizaci struktury
databáze s naším modelem. Proto se často používá v kombinaci s metodou
EnsureDeleted()
, pomocí které před zavoláním metody
EnsureCreated()
nejprve smažeme celou databázi.
Generování databáze s použitím kombinace těchto dvou metod se využívá v situacích, kdy nám nesejde na zachování dat uložených v databázi. Nejčastěji je to při prototypování, testování nebo pro lokální cache.
Metodu EnsureCreated()
nelze použít v kombinaci s
migracemi.
Vygenerování naší databáze
Nyní se v našem projektu přesuneme do souboru Program.cs
. Zde
si vytvoříme instanci databázového kontextu FirstDbContext
a
použijeme ji k vygenerování naší databáze:
FirstDbContext dbContext = new FirstDbContext(); if (dbContext.Database.EnsureCreated()) Console.WriteLine("Databáze byla právě vytvořena"); dbContext.Dispose();
K vygenerování databáze používáme metodu EnsureCreated()
.
Tu nenajdeme přímo v databázovém kontextu, ale na instanci třídy
DatabaseFacade
, která je uložena ve vlastnosti
Database
databázového kontextu. V případě vygenerování
databáze vrací metoda EnsureCreated()
hodnotu true
,
na kterou reagujeme vypsáním hlášky do konzole. V opačném případě
metoda vrací hodnotu false
.
Po dokončení práce s kontextem nesmíme zapomenout ukončit
spojení a uvolnit zdroje zavoláním metody
Dispose()
.
Blok using
Metoda Dispose()
pochází z rozhraní IDisposable
,
které databázový kontext implementuje. Toto rozhraní implementují třídy,
jejichž instance potřebují po vykonání své práce po sobě provést
úklid. Jazyk C# nabízí pro toto rozhraní speciální syntaxi v podobě bloku
using
, který zajistí automatické zavolání metody
Dispose()
na svém konci.
Přepišme před chvílí napsaný kód tak, aby využíval blok
using
:
using (FirstDbContext dbContext = new FirstDbContext()) { if (dbContext.Database.EnsureCreated()) Console.WriteLine("Databáze byla právě vytvořena"); }
Spuštění programu
Databázi vygenerujeme spuštěním programu. Do konzole se nám vypíše očekávaná hláška:
Konzolová aplikace
Databáze byla právě vytvořena
Při každém dalším spuštění aktuálního programu se hláška již nevypíše. Databáze bude totiž již vygenerovaná.
Zobrazení databáze
Na vygenerovanou LocalDB se ve Visual Studio podíváme přes nástroj
SQL Server Object Explorer. V horní nabídce Visual Studio klikneme na
View a zvolíme SQL Server Object Explorer. K tabulce
Authors
naší databáze se postupně proklikáme přes SQL
Server → (localdb)MSSQLLocalDB → Databases → FirstEFCoreDatabase →
Tables:
Dvojklikem na tabulku si zobrazíme její definici, kterou Entity Framework Core vygeneroval:
V SQL kódu si můžeme všimnout, že sloupec Id
byl díky
atributu [Key]
vlastnosti Id
opravdu nastaven jako
primární klíč tabulky a že mu navíc byla nastavena i
vlastnost IDENTITY
. Tato vlastnost nám zajistí
automatické číslování všech záznamů, a nebudeme tak
muset zadávat Id
autorů. Ve skutečnosti vlastnost
Id
nebudeme moci nastavit na nic jiného než na výchozí hodnotu
datového typu int
, tedy 0
.
Smazání databáze
Jak již bylo zmíněno výše, metoda EnsureCreated()
se často
používá v kombinaci s metodou EnsureDeleted()
, kdy si na
začátku programu nejprve metodou EnsureDeleted()
smažeme celou
databázi a hned nato ji znovu vygenerujeme metodou
EnsureCreated()
. Učiníme tak i my, abychom při našem
prototypování vždy pracovali s čistou databází:
using (FirstDbContext dbContext = new FirstDbContext()) { if (dbContext.Database.EnsureDeleted()) Console.WriteLine("Databáze byla právě smazána"); if (dbContext.Database.EnsureCreated()) Console.WriteLine("Databáze byla právě vytvořena"); }
V případě smazání existující databáze metoda
EnsureDeleted()
vrací hodnotu true
, na kterou
reagujeme vypsáním hlášky do konzole. V opačném případě metoda vrací
hodnotu false
.
Po každém spuštění aktuálního programu uvidíme tento výstup:
Konzolová aplikace
Databáze byla právě smazána
Databáze byla právě vytvořena
Tím pro dnešek lekci skončíme.
V příští lekci, První dotazy na databázi v Entity Framework Core a C# .NET, si ukážeme první dotazy na vkládání a výběr záznamů z databáze. Zmíníme se taktéž o důležitém konceptu sledování změn.
Měl jsi s čímkoli problém? Zdrojový kód vzorové aplikace je ke stažení každých pár lekcí. Zatím pokračuj dál, a pak si svou aplikaci porovnej se vzorem a snadno oprav.