| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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.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 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 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 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 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