Lekce 3 - Přístupy pro práci s relačními databázemi v .NET
V minulé lekci, Vytvoření lokální databáze ve Visual Studio, jsme si připravili databázi slovíček.
Dnešní tutoriál bude teoretický, uvedeme si problémy relačního a objektového světa a dále přístupy, jakými můžeme s databází v C# .NET pracovat.
Rozpor objektového a relačního přístupu
Objektový svět a svět relačních databází (svět relační) jsou velmi rozdílné. Jedná se o 2 odlišné filozofie, o kterých si zde troufnu prohlásit, že jsou neslučitelné.
Relační databáze jsou ověřený způsob jak pracovat s daty. I když existují i databáze plně objektové, firmám se do nich nyní nevyplatí investovat peníze a proto se zatím neprosadily. Po revoluci v programování a příchodu objektů samozřejmě nastal problém s ukládáním dat, jelikož relační databáze objektově nefungují a objekty ukládat neumí. Existuje několik možností, jak se s tímto vypořádat.
1. Neobjektové programování
První možností je samozřejmě programovat úplně bez objektů. Tím bychom však šli proti proudu, nemohli bychom používat žádné komponenty 3. stran a náš kód by byl velmi nekvalitní. Jelikož C# je objektový jazyk, ani by to v něm dost dobře nešlo.
2. Databázový Wrapper
Přístup tzv. wrapperu nám umožňuje s databází pracovat jako s objektem, nicméně komunikujeme s ní stále v jejím jazyce SQL. Mícháme tedy objektový a relační kód. Přístup je jakýmsi kompromisem a vyžaduje filozofii OOP trochu ohnout. Výhodou je zachování výkonu a schopností databáze za cenu mírné degradace myšlenek OOP.
Data z databáze vidíme nejčastěji jako hodnoty v tabulce (ta je objektem) a přicházíme o možnost přidělit entitám nějakou funkcionalitu. Tu místo toho sdružujeme do tzv. manažerů. Lze i částečně mapovat data na existující třídy, nicméně plnohodnotného konceptu objektového modelu nedosáhneme.
3. Objektově relační mapování
Objektově relační mapování (ORM) jde ortodoxně za myšlenkou OOP. Z databáze tedy místo pole hodnot dostáváme rovnou objekty a ty na sobě mají metody. V jazyce SQL vůbec nekomunikujeme, tabulky v databázi vidíme jako kolekce objektů, se kterými můžeme pracovat běžnými prostředky jazyka. Jsme vlastně úplně odstíněni od toho, že pracujeme s relační databází. Zní to skvěle, že?
Háček je samozřejmě v tom, že na pozadí dochází k velké degradaci výkonu databáze, SQL dotazy se generují automaticky a jsou často neefektivní. Dalším problémem ORM je, že je velmi složité (ne k použití, ale k naprogramování). C# má naštěstí perfektně odladěné ORM přímo v sobě, čili nemusíme nic řešit. Naopak např. zprovoznit ORM v PHP není nic jednoduchého a tam preferuji přístup wrapperu.
Názory na ORM jsou velmi kontroverzní, např. že samotná jeho myšlenka je nesprávná, jelikož generovaný SQL kód zkrátka nemůže být efektivní a je nutné pomýšlet na jeho konečnou podobu, odstínění tedy není úplné. Osobně mám k ORM neutrální postoj a pokud mi někdo spolu s jazykem poskytne standardizované a odladěné ORM, rád ho použiji. Pokud ne, obejdu se bez něj.
4. Objektové databáze
Kromě databází relačních existují i již zmíněné databáze objektové. Ty řeší problém neslučitelnosti objektového a relačního přístupu. Poskytují stejný komfort, jako ORM, ale vnitřně není třeba data převádět do tabulek, ukládají se rovnou jako objekty. Teoreticky neexistuje výkonnostní ani jíný důvod, proč by neměly nahradit databáze relační. V praxi se ale bohužel téměř nepoužívají a můžeme jen doufat, že se to časem změní. Zájemci se mohou podívat např. na projekt MongoDB.
Možnosti připojení k databázi
V .NETu máme několik možností, jak databázi v naší aplikaci používat. Nebudu je detailně popisovat, pouze si ke každé možnosti krátce něco řekněme. Je důležité, abyste věděli, že existují. Databáze jsou velmi rozsáhlé téma, když danou možnost budete potřebovat, zjistíte si o ni více.
Připojená aplikace
Přístup připojené aplikace použijeme ve chvíli, kdy potřebujeme data
často v reálném čase číst nebo měnit. Pomocí tříd
DataReader
, Command
a Connection
posíláme databázi přímo příkazy v jazyce SQL a dostáváme výsledky.
Situaci jsem znázornil na obrázku:

Odpojená aplikace - DataSet
Přístup odpojené aplikace funguje tak, že máme v operační paměti tzv.
DataSet
, který v sobě obsahuje data z databáze. Aplikace pracuje
s DataSetem
a občas se DataSet
sesynchronizuje s
ostrou databází na serveru (disku). Za cenu méně aktuálních dat
získáváme zvýšení rychlosti a pohodlnější práci. Tento přístup
shrnuje komponenta ADO.NET, která je součástí .NET frameworku.
DataSet
v sobě obsahuje tabulky, tabulka řádky a řádek
sloupce. Tabulka je objekt, můžeme do ní řádky přidávat a upravovat je
bez psaní SQL kódu. Když chceme spustit na databázi nějaký příkaz,
použijeme DataAdapter
, pomocí kterého si naplníme
DataSet
daty. Příkazy již musíme psát v jazyce SQL dané
databáze.

Máme tedy určitou objektovou abstrakci, s tabulkami pracujeme objektově, ale data jsou stále jen sloupečky v tabulce, ne instance nějakých objektů. Také stále používáme jazyk SQL. Z hlediska výše uvedených přístupů se jedná o wrapper.
LINQ To SQL
LINQ to SQL poskytuje kompletní objektovou abstrakci nad databází
(objektově relační mapování). S databází pracujeme jako kdyby to byl
např. List
objektů a vůbec neřešíme SQL dotazy, nevíme o
tabulkách ani sloupcích, vše se děje na pozadí automaticky, dotaz nám
vrací rovnou plnohodnotné objekty. Cena za takový luxus je horší
optimalizace dotazů, která ale většinou nevadí.
V naší aplikaci figuruje tzv. DataClasses
, což je objektová
struktura databáze. Obsahuje třídy pro jednotlivé tabulky, sloupce tabulky
jsou vlastnosti daných tříd. V aplikaci komunikujeme pouze s
DataClasses
, ta potom na pozadí pomocí LINQ to SQL komunikuje s
databází a provádí za nás SQL dotazy. My s jazykem SQL vůbec nepřijdeme
do styku a s databází pracujeme jako s objektovou strukturou v operační
paměti.

Důkladný popis této technologie si necháme na příště, stejně jako vytvoření první databázové aplikace.
Entity Framework
Entity framework jde ještě dále, než LINQ to SQL. Jedná se o konkurenční a pokročilejší technologii k LINQ to SQL. Navíc umí např. vazbu M:N. Tento přístup se nejlépe používá a pokud nejste nějak limitovaní architekturou dané aplikace nebo výkonem, je dobrou volbou pro většinu aplikací.
V našem kurzu si představíme postupně všechny přístupy, každý se hodí k něčemu jinému a do praxe byste o nich měli mít přehled.
V příští lekci, Připojená databázová aplikace v C# .NET, si představíme přístup připojené aplikace.