SqlDataReader je veľmi efektívny pri načítavaní údajov z databázy, pretože obsahuje vždy jeden riadok a načítava údaje postupne. Koncept (algoritmus) načítavania údajov je defacto je pri každom načítavaní jednotný. Problémom je ako dostať dáta z readeru a spracovať ich a mať počas toho aj otvorené pripojenie do databázy (SqlDataReader samozrejme vyžaduje počas čítania aktívne pripojenie).
Najľahšie sa dá napísať všeobecná metóda pre vykonávanie SQL príkazov cez metódu SqlCommand.ExecuteNonQuery(). Jej návratová hodnota je void, netreba ju teda nijako spracovať a nič vracať z vlastnej metódy.
Metóda ExecuteScalar() sa dá ľahko zaobaliť: buď bude metóda vracať Object, ktorý vracia ExecuteScalar(), alebo pri použití generík môže zaobaľujúca metóda vracať špecifický typ daný generickým parametrom.
Pri použití ExecuteReader() treba údaje nejako spracovať.
Práca so SqlDataReader-om
-
Pripravíme si objekt SqlConnection a SqlCommand
-
Otvoríme spojenie do databázy
-
Spracujeme údaje zo SqlDataReader-u
-
Uzatvoríme spojenie s databázou
-
Zrušíme objekty pomocou Dispose() metódy
-
Vrátime spracované údaje
Ako som spomenul, problém spočíva v tom, ako vytvoriť všeobecnú metódu, ktorá údaje zo SqlDataReader-u vytvorí špecifický dátový typ (IList, dátová tabuľka, užívateľské konto, produkt…) a vráti ho.
Prvá časť, ktorá je generická v tejto metóde, je návratová hodnota. Pred otvorením spojenia s databázou nainštancujeme návratovú premennú na východziu hodnotu operátorom default(). (Operátor default() inicializuje číselné typy na hodnotu 0, referenčné typy na null a v štruktúrach nastaví číselné a referenčné typy obdobne.) Po získaní objektu SqlDataReader vytvoríme inštanciu návratového objektu, poupratujeme za sebou a vrátime výsledok.
Druhá generická časť je vytvorenie objektu. Na vstupe máme objekt SqlDataReader, na výstupe generický typ T. Generická metóda by vyzerala takto:
public T DataReaderHandle<T>(SqlDataReader reader);
Keď túto metódu zavoláme v časti ?spracovanie údajov?, vykonávanie sa tak presunie do užívateľského kódu a po vytvorení objektu sa vráti k štandardnému toku programu. Tu využijeme callback pomocou delegátov. Delegát určuje predpis metódy, ktorá má byť zavolaná a je možné ho použiť ako parameter funkcie. Ukážková metóda DataReaderHandle bude ako delegát vyzerať takto:
public delegate T DataReaderHandle<T>(SqlDataReader reader);
Ešte treba pridať delegát ako parameter do metódy a vyvolať metódu, na ktorú ukazuje:
Už len stačí napísať metódy, ktoré budú spracovávať SqlDataReader a vytvárať patričné objekt. Keď máme triedu User so statickou metódou ParseUser vracajúcu objekt User, stačí zavolať ExecuteReader takto:
User user = DbLayer.ExecuteReader<User>(User.ParseUser, „UserDetails“, sqlParams);
Knižnica DbLayer: /weblog/media/dotnet/DbLayer.cs
Jan Peterka says:
s tím parameterom do metódy to znie zaujímavo