Poodhalené ADO.NET

11. října 2002

ADO.NET představuje soubor tříd pro přístup k datům v technologii .NET. Pokud jste však zvyklí pracovat s klasickým ADO (ActiveX Data Objects), přeorientovat se na ADO.NET pro vás nebude tak obtížné.

Novinky, které přináší ADO.NET lze rozdělit na ty, které jsou součástí mechanismu přístupu k datům a na ty, které vyžadují jiný uživatelský (myšleno programátorský) přístup k této technologii. Nejpatrnější změnou patřící do první skupiny je přenos dat založený na XML. Druhou skupinu reprezentuje např. fakt, že v ADO.NET nenajdete žádný Recordset.

Funkčnost Recordsetu je v ADO.NET rozdělena do jiných objektů. Prvním je DataReader, který umožňuje použití souboru záznamů, které jsou výsledkem SQL dotazu. Chová se stejně jako forward-only server-side kursor v klasickém ADO. Další dva objekty, DataSet a DataAdapter, umožňují přenesení dat do lokální cache klienta (tím může být widowsový nebo i webový formulář) a práci s těmito daty i ve stavu, kdy je přerušeno spojení s databází. Jedná se tedy o rozšíření a zlepšení funkčnosti client-side kursorů, jak je známe z klasického ADO. Navíc DataSet a DataAdapter mohou obsahovat datové struktury, které lze přirovnat k více relačně provázaným Recordsetům. V ADO.NET však nenajdete třeba možnost aktualizovat data (update) při otevřeném spojení klienta s databází za pomoci pesimistického zamykání záznamů, což je v klasickém ADO běžné. Celkově lze říci, že ADO.NET je projektováno pro použití v síťovém (a ještě více webovém) prostředí.

DataReader

V ADO.NET najdete třídy, které jsou velmi podobné těm z ADO – OleDbConnection, OleDbCommand a OleDbDataReader. Tyto objekty spolupracují s definovaným OLE DB providerem jako v klasickém ADO.

Pro práci s Microsoft SQL Serverem lze použít i speciální sadu tříd SQLConnection, SQLCommand a SQLDataReader, které poskytují programátorovi vyšší výkon.

Ukažme příklad použití objektu DataReader k naplnění ListBoxu názvy zboží (všechny výpisy kódu v tomto článku jsou uvedeny ve Visual Basicu).

Imports System.Data
Imports System.Data.OleDb

Dim con As New OleDbConnection(strConn)
Try
  con.Open()
  Dim cmd As New OleDbCommand(„select * from zbozi“, con)
  Dim dtr As OleDbDataReader = cmd.ExecuteReader()
  While dtr.Read()
    listbox1.Items.Add(dtr(„nazev“))
  End While
Catch err As OleDbException
  Dim i As Integer
  For i = 0 To err.Errors.Count – 1
   MessageBox.Show(„Index #“ + i.ToString() + ControlChars.Cr _
   + „Message: “ + myException.Errors(i).Message + ControlChars.Cr _
   + „Native: “ + myException.Errors(i).NativeError.ToString() + ControlChars.Cr _
   + „Source: “ + myException.Errors(i).Source + ControlChars.Cr _
   + „SQL: “ + myException.Errors(i).SQLState + ControlChars.Cr)
  Next i
Finally
  If con.State.ToString()=“Open“ Then con.Close
End Try

strConn musí obsahovat platný Connection String k databázi. Za povšimnutí stojí, že ve smyčce While nenajdete metodu MoveNext známou z ADO. Metoda Read čte nejen data, ale zároveň posunuje kursor vpřed nebo vrací hodnotu False, pokud již není co číst. Programátoři, kteří na MoveNext často zapomínali, toto zjednodušení jistě uvítají.

DataReader využijete všude tam, kde forward-only kursor v ADO, typicky např. plnění seznamů hodnotami, tvorbě jednoduchých tiskových sestav apod.

DataSet

DataSet je výsledkem úsilí spojit klasické ADO s XML datovým formátem. DataSet obsahuje tabulární data jedné nebo více tabulek ve formě XML. Tato data mohou být zpracovávána samostatně nebo mohou mít mezi sebou definovány relace podobně jako v relační databázi. DataSet je třída, která se nestará o spojení s databází nebo o SQL dotazy. Jedná se o klientský nástroj pro zpracování dat.

Existují dva způsoby, jak naplnit DataSet daty. Prvním z nich je použití objektu DataAdapter, který vrací výsledek SQL dotazu ve formě XML. Druhou možností je pracovat přímo s XML. DataSet má metody s jejichž pomocí umí číst a zapisovat XML data a schémata. Umí také spolupracovat s objektem XMLDataDocument.

Jak tedy naplnit část DataSetu daty? Nejjednodušší působ je využití DataAdapter:

Dim con As OleDbConnection = New OleDbConnection(strConn)
Dim cmd As New OleDbCommand(_
  „select id, nazev from zbozi where dodavatel=’Alfa Company'“, con)
Dim custDA As OleDbDataAdapter = New OleDbDataAdapter()
custDA.SelectCommand = cmd
Dim dts As DataSet = New DataSet()
custDA.Fill(dts, „Dodavky_Alfa“)

Uvedený kód naplní jeden objekt DataTable výsledkem SQL dotazu. Konkrétní instance objektu DataTable se bude jmenovat „Dodavky_Alfa“ a pod tímto jménem se také bude v DataSetu zpracovávat. Spojení s databází zajišťuje metoda Fill, která implicitně otevírá spojení, které používá DataAdapter (pokud není již otevřeno). Po naplnění DataSetu je spojení zase automaticky zavřeno. Metody Open a Close však lze uvést i explicitně pro rozsáhlejší práci, např. použití více instancí DataAdapteru.

Vygenerované XML schéma (XSD) a XML data lze získat takto:
MsgBox(dts.GetXmlSchema(), ,“XML schéma“)
MsgBox(dts.GetXmlData(), ,“XML data“)
Následně by bylo možné podobným kódem naplnit i další instanci DataTable stejného DataSetu. Tím se samozřejmě změní i dts.GetXmlSchema() a dts.GetXmlData(). Tyto vlastnosti se váží k DataSetu jako celku a nikoli k jednotlivým tabulkám.

Při práci s klasickým ADO Recordsetem musí programátor citlivě používat serverové a klientské kursory s ohledem na to, že některé operace (především nesekvenční přístup k datům metodami jako MoveFirst nebo AbsolutePosition) jsou na serverové straně velmi pomalé. U DataSetu tento problém odpadá, data jsou natažena vždy v cache na klientské straně.

Pokud je alespoň jedna tabulka DataSetu naplněna daty (viz předcházející kód), lze s nimi pracovat třeba takto:

Dim dr() As DataRow
Dim i As Integer
dr = dts.Tables(„Dodavky_Alfa“).Select(„nazev >= ‚A'“)
For i=0 To UBound(dr)
  listbox1.Items.Add(CStr(dr(i)(„nazev“)))
Next i

Příklad naplní ListBox názvy zboží z tabulky Dodavky_Alfa DataSetu. Názvy musejí splňovat podmínku, že jsou větší nebo rovny ‚A‘. Pracuje se pouze s jedinou tabulkou. Pokud by tabulek v DataSetu bylo víc, ostatní tabulky se v tomto kódu zcela ignorují.

Relace mezi tabulkami

V předcházejícím textu byl sice vysvětlen rozdíl mezi Recordsetem (ADO) a DataSetem (ADO.NET), nicméně použitý začátečnický příklad pro práci s DataSetem dostatečně nedemonstruje popsané rozdíly. Na ty se zaměříme nyní, při definici relací mezi tabulkami DataSetu. Předpokládejme, že máme v DataSetu datové tabulky Zbozi a Dodavatel, které lze vzájemně sklíčovat pomocí ID jejich záznamů. Relaci do DataSetu zadáte takto:

Dim parentCol As DataColumn
Dim childCol As DataColumn
parentCol = DataSet1.Tables(„Dodavatel“).Columns(„ID“)
childCol = DataSet1.Tables(„Zbozi“).Columns(„ID“)
Dim relCustOrder As DataRelation = _
  DataSet1.Relation.Add(„MojeRelace“, parentCol, childCol)

Následně můžeme do ListBoxu vypsat vždy dodavatele a pod něj seznam jím dodávaných druhů zboží:

Dim dr() As DataRow
Dim drChildren() As DataRow
Dim i,j As Integer
dr = DataSet1.Tables(„Dodavatel“).Select(„nazev_dodavatele ASC“)
For i=0 To UBound(dr)
  listbox1.Items.Add(CStr(dr(i)(„nazev_dodavatele“)))
  drChildren=dr(i).GetChildRows(relCustOrder)
  For j=0 To UBound(drChildren)
    listbox1.Items.Add(“ “ & CStr(drChildren(j)(„nazev_zbozi“)))
  Next j
Next i

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Předchozí článek Toulky po webu 10.
Další článek chrudim.cz
Štítky: Články

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *