Interval.cz
PoodhalenΘ ADO.NET

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


David Morkes (11.10. 2002)

Redakce Interval.cz |  Inzerce na Interval.cz |  Hledßme novΘ autory ISSN 1212-8651 
 ⌐ Zoner software, s.r.o., vÜechna prßva vyhrazena, tento server dodr₧uje prßvnφ p°edpisy o ochran∞ osobnφch ·daj∙.