3. diel - Prístupy pre prácu s relačnými databázami v .NET
V minulej lekcii, Vytvorenie lokálnej databázy vo Visual Studio, sme si pripravili databázu slovíčok.
Dnešný tutoriál bude teoretický, uvedieme si problémy relačného a objektového sveta a ďalej prístupy, akými môžeme s databázou v C# .NET pracovať.
Rozpor objektového a relačného prístupu
Objektový svet a svet relačných databáz (svet relačný) sú veľmi rozdielne. Ide o 2 odlišné filozofie, o ktorých si tu trúfnem vyhlásiť, že sú nezlučiteľné.
Relačné databázy sú overený spôsob ako pracovať s dátami. Aj keď existujú aj databázy plne objektové, firmám sa do nich teraz neoplatí investovať peniaze a preto sa zatiaľ nepresadili. Po revolúcii v programovaní a príchode objektov samozrejme nastal problém s ukladaním dát, pretože relačné databázy objektovo nefungujú a objekty ukladať nevedia. Existuje niekoľko možností, ako sa s týmto vysporiadať.
1. Neobjektové programovanie
Prvou možnosťou je samozrejme programovať úplne bez objektov. Tým by sme však šli proti prúdu, nemohli by sme používať žiadne komponenty 3. strán a náš kód by bol veľmi nekvalitný. Keďže C# je objektový jazyk, ani by to v ňom dosť dobre nešlo.
2. Databázový Wrapper
Prístup tzv. wrappera nám umožňuje s databázou pracovať ako s objektom, ale komunikujeme s ňou stále v jej jazyku SQL. Miešame teda objektový a relačný kód. Prístup je akýmsi kompromisom a vyžaduje filozofiu OOP trochu ohnúť. Výhodou je zachovanie výkonu a schopností databázy za cenu miernej degradácie myšlienok OOP.
Dáta z databázy vidíme najčastejšie ako hodnoty v tabuľke (tá je objektom) a prichádzame o možnosť prideliť entitám nejakú funkcionalitu. Tú namiesto toho združujeme do tzv. manažérov. Je možné aj čiastočne mapovať dáta na existujúce triedy, avšak plnohodnotný koncept objektového modelu nedosiahneme.
3. Objektovo relačné mapovanie
Objektovo relačné mapovanie (ORM) ide ortodoxne za myšlienkou OOP. Z databázy teda namiesto poľa hodnôt dostávame rovno objekty a tie na sebe majú metódy. V jazyku SQL vôbec nekomunikujeme, tabuľky v databáze vidíme ako kolekcia objektov, s ktorými môžeme pracovať bežnými prostriedkami jazyka. Sme vlastne úplne odtienení od toho, že pracujeme s relačnou databázou. Znie to skvele, že?
Háčik je samozrejme v tom, že na pozadí dochádza k veľkej degradácii výkonu databázy, SQL dotazy sa generujú automaticky a sú často neefektívne. Ďalším problémom ORM je, že je veľmi zložité (nie na použitie, ale na naprogramovanie). C# má našťastie perfektne odladené ORM priamo v sebe, čiže nemusíme nič riešiť. Naopak napr. sprevádzkovať ORM v PHP nie je nič jednoduché a tam preferujem prístup wrappera.
Názory na ORM sú veľmi kontroverzné, napr. že samotná jeho myšlienka je nesprávna, pretože generovaný SQL kód skrátka nemôže byť efektívny a je nutné pomýšľať na jeho konečnú podobu, odtienenie teda nie je úplné. Osobne mám k ORM neutrálny postoj a pokiaľ mi niekto spolu s jazykom poskytne štandardizované a odladené ORM, rád ho použijem. Ak nie, zaobídem sa bez neho.
4. Objektové databázy
Okrem databáz relačných existujú aj už spomínané databázy objektové. Tie riešia problém nezlučiteľnosti objektového a relačného prístupu. Poskytujú rovnaký komfort ako ORM, ale vnútorne nie je potrebné dáta prevádzať do tabuliek, ukladajú sa rovno ako objekty. Teoreticky neexistuje výkonnostný ani iný dôvod, prečo by nemali nahradiť databázy relačné. V praxi sa ale bohužiaľ takmer nepoužívajú a môžeme len dúfať, že sa to časom zmení. Záujemcovia sa môžu pozrieť napr. na projekt MongoDB.
Možnosti pripojenia k databáze
V .NETe máme niekoľko možností, ako databázu v našej aplikácii používať. Nebudem ich detailne popisovať, iba si ku každej možnosti krátko niečo povedzme. Je dôležité, aby ste vedeli, že existujú. Databázy sú veľmi rozsiahle témy, keď danú možnosť budete potrebovať, zistíte si o ňu viac.
Pripojená aplikácia
Prístup pripojenej aplikácie použijeme vo chvíli, keď potrebujeme dáta
často v reálnom čase čítať alebo meniť. Pomocou tried
DataReader
, Command
a Connection
posielame databázu priamo príkazy v jazyku SQL a dostávame výsledky.
Situáciu som znázornil na obrázku:
Odpojená aplikácia - DataSet
Prístup odpojenej aplikácie funguje tak, že máme v operačnej pamäti
tzv. DataSet
, ktorý v sebe obsahuje dáta z databázy. Aplikácia
pracuje s DataSetem
a občas sa DataSet
zosynchronizuje s ostrou databázou na serveri (disku). Za cenu menej
aktuálnych dát získavame zvýšenie rýchlosti a pohodlnejšiu prácu. Tento
prístup sumarizuje komponent ADO.NET, ktorý je súčasťou .NET
frameworku.
DataSet
v sebe obsahuje tabuľky, tabuľka riadky a riadok
stĺpca. Tabuľka je objekt, môžeme do nej riadky pridávať a upravovať ich
bez písania SQL kódu. Keď chceme spustiť na databázu nejaký príkaz,
použijeme DataAdapter
, pomocou ktorého si naplníme
DataSet
dátami. Príkazy už musíme písať v jazyku SQL danej
databázy.
Máme teda určitú objektovú abstrakciu, s tabuľkami pracujeme objektovo, ale dáta sú stále iba stĺpčekmi v tabuľke, nie inštancie nejakých objektov. Tiež stále používame jazyk SQL. Z hľadiska vyššie uvedených prístupov sa jedná o wrapper.
LINQ To SQL
LINQ to SQL poskytuje kompletnú objektovú abstrakciu nad databázou
(objektovo relačné mapovanie). S databázou pracujeme ako keby to bol napr.
List
objektov a vôbec neriešime SQL otázky, nevieme o
tabuľkách ani stĺpcoch, všetko sa deje na pozadí automaticky, dotaz nám
vracia rovno plnohodnotné objekty. Cena za taký luxus je horšia
optimalizácia otázok, ktorá ale väčšinou nevadí.
V našej aplikácii figuruje tzv. DataClasses
, čo je objektová
štruktúra databázy. Obsahuje triedy pre jednotlivé tabuľky, stĺpce
tabuľky sú vlastnosti daných tried. V aplikácii komunikujeme iba s
DataClasses
, tá potom na pozadí pomocou LINQ to SQL komunikuje s
databázou a vykonáva za nás SQL otázky. My s jazykom SQL vôbec neprídeme
do styku as databázou pracujeme ako s objektovou štruktúrou v operačnej
pamäti.
Dôkladný popis tejto technológie si necháme nabudúce, rovnako ako vytvorenie prvej databázovej aplikácie.
Entity Framework
Entity framework ide ešte ďalej, než LINQ to SQL. Ide o konkurenčnú a pokročilejšiu technológiu k LINQ to SQL. Navyše vie napr. väzbu M:N. Tento prístup sa najlepšie používa a pokiaľ nie ste nejako limitovaní architektúrou danej aplikácie alebo výkonom, je dobrou voľbou pre väčšinu aplikácií.
V našom kurze si predstavíme postupne všetky prístupy, každý sa hodí k niečomu inému a do praxe by ste o nich mali mať prehľad.
V budúcej lekcii, Pripojená databázová aplikácia v C# .NET, si predstavíme prístup pripojenej aplikácie.