Zßkladnφm objektem pro prßci s databßzemi v .NET Frameworku je DataSet. Je to t°φda, kterou najdeme ve jmennΘm prostoru System.Data a kterß m∙₧e uchßvat tabulky (objekty DataTable) a vztahy mezi nimi (objekty DataRelations).
DataTable je objekt reprezentujφcφ tabulku. Obsahuje kolekce Columns (sloupce, reprezentuje je objekt DataColumn) a Rows (°ßdky neboli zßznamy, reprezentovßny objektem DataRow), p°es kterΘ m∙₧eme p°istupovat k dat∙m. Jak? Objekt DataRow mß vlastnost Item, kterß m∙₧e jako parametr p°ijmout sloupec danΘ tabulky. Tak₧e pokud budeme chtφt vypsat takovou tabulku do strßnky, m∙₧eme pou₧φt t°eba nßsledujφcφ postup:
Response.Write("<table>") Response.Write("<tr>") For Each DataColumn c In tabulka.Columns Response.Write("<td><b>" + c.ColumnName) Next c For Each DataRow r In tabulka.Rows Response.Write("<tr>") For Each DataColumn c In tabulka.Columns Response.Write("<td>" + r(c).ToString()) Next c Next r Response.Write("</table>")
Je to o mnoho elegantn∞jÜφ prßce s daty ne₧ v p°φpad∞ objektu SqlDataReader, nemyslφte? Aby jsme vÜak m∞li s Φφm pracovat, musφme objekt DataSet naplnit daty z databßze. K tomu poslou₧φ objekt SqlDataAdapter - tomu m∙₧eme p°edat SQL dotaz a pak zavolat jeho metodu Fill, kterß navrßcenß data p°evede do DataSetu.
Dim conn As SqlConnection(connString) Dim adap As SqlDataAdapter("SELECT * FROM tabulka WHERE autor = 'xyz'", conn) Dim ds As DataSet = new DataSet() adap.Fill(ds, "tabulka")
Nynφ mßme DataSet pln² dat z tabulky tabulka. M∙₧eme prochßzet jednotlivΘ °ßdky a libovoln∞ s nimi pracovat. Nap°φklad p°idßnφ novΘho °ßdku se provßdφ volßnφm metody Add objektu DataRowCollection, co₧ je obsah DataTable.Rows. Jako parametr m∙₧eme zadat pole objekt∙ nebo p°φmo DataRow (ten m∙₧eme vytvo°it pomocφ metody NewRow objektu DataTable).
Dim °ßdek As DataRow = tabulka.NewRow() °ßdek("ID") = 15 °ßdek("Jmeno") = "Lukas" °ßdek("Prijmeni") = "Lansky" tabulka.Rows.Add(°ßdek)
Odstranit °ßdek je mo₧no pomocφ metody Remove:
tabulka.Rows(1).Remove()
Editovat libovoln² zßznam je snadnΘ:
tabulka.Rows(1)("Jmeno") = "Ondrej"
U₧iteΦnß je mo₧nost zm∞ny provedenΘ v tΘto struktu°e reflektovat zp∞t do databßze.
Ka₧d² °ßdek ka₧dΘ tabulky v DataSetu mß vlastnost RowChanged, kterß oznamuje, jestli se °ßdek zm∞nil od naΦtenφ z databßze. RowChanged m∙₧e nab²vat hodnot Unchanged (nezm∞n∞n), New (nov²), Deleted (vymazan²), Modified (vymazan²). Pak mß DataRow metodu AcceptChanges, kterß zaktualizuje databßzi a uvede jejφ obsah na pravou mφru s obsahem nßmi zm∞n∞nΘho DataRow. Tuto metodu mß i DataTable a DataSet - v tomto p°φpad∞ je aktualizovßna celß tabulka / DataSet.
Po zavolßnφ AcceptChanges se vlastnosti RowChanged dotΦen²ch zßznam∙ zm∞nφ na Unchanged - proto₧e oproti databßzi je hodnota nezm∞n∞nß.
VeÜkerou dalÜφ prßci s databßzφ m∙₧eme tedy omezit na prßci s DataSetem a jeho aktualizace s touto databßzφ. ASP.NET nßm ale nabφzφ dalÜφ zajφmavΘ mo₧nosti co se t²Φe zobrazovßnφ t∞chto dat u₧ivateli.
Minul² dφl jsme zakonΦili v²pisem zdrojovΘho k≤du, kter² je v technologiφch ASP a PHP stßle b∞₧n². Data jsou ulo₧ena v objektu a my nad nφm iterujeme a postupn∞ je vypisujeme. Existujφ vÜak elegantn∞jÜφ metody, kter²mi m∙₧eme zabezpeΦit v²stup z databßze u₧ivateli.
Technologie svßzßnφ dat (Data Binding) nßm v ASP.NET umo₧≥uje vypisovat snadno informace do strßnky. NejjednoduÜÜφ metoda svßzßnφ vypadß takto:
<script runat="server"> Dim jmeno = "Ond°ej" Sub Page_Load() Page.DataBind() End Sub </script> U₧ivatel se jmenuje <%# jmeno %>
Z°ejm∞ jste pochopili, ₧e na mφsto toho divn∞ ohraniΦenΘho identifikßtoru jmeno se doplnφ text "Ond°ej". Zp∙sobila to metoda objektu Page (kter² p°ekvapiv∞ reprezentuje vlastnφ strßnku) DataBind. Tento p°φpad ovÜem neukazuje technologii v plnΘ sφle, nebo¥ by staΦilo nahradit uvozenφ "<%#" za "<%=".
Uka₧me si pon∞kud sofistikovan∞jÜφ vyu₧itφ:
<script runat="server"> Dim jmeno As String = "Ond°ej" Dim moznaJmena() As String = {"TomßÜ", "Josef", "Mat∞j", "Jakub", "Ond°ej"} Sub Page_Load() Page.DataBind() End Sub </script> U₧ivatel se jmenuje <%# jmeno %>.<br> <form runat="server"> Nebo ne? <asp:ListBox DataSource="<%# moznaJmena %>" runat="server"> </form>
D∙le₧it∞jÜφ ne₧ p°φmΘ vklßdßnφ obsahu prom∞nnΘ do strßnky je mo₧nost svßzat data z databßze se serverov²m ovlßdacφm prvkem. Ten takto dostane do ruky p°φsluÜn² datov² zdroj - a je z°ejmΘ, ₧e to m∙₧e b²t t°eba i DataSet. Nabφzφ to bohat∞ mo₧nosti...
P°edstavme si nap°φklad prvek, kter² p°evezme zdroj dat, projde jeho prvky, zobrazφ je ve form∞ tabulky a t°eba nabφdne strßnkovßnφ bez prßce programßtora webovΘ aplikace. Beze sporu to mo₧nΘ je - a prvky .NETu pro prßci t∞chto mo₧nostφ pln∞ vyu₧φvajφ.
Jako prvnφ si ukß₧eme prvek Repeater. Je to velmi jednoduchß metoda pro zobrazenφ dat podle definovanΘ Üablony. Neumφ strßnkovßnφ ani editaci dat, p°esto prßci zjednoduÜuje.
Setkßvßme se s tφmto typem serverovΘho ovlßdacφho prvku poprvΘ. Sßm o sob∞ nemß ₧ßdn² v²znam, musφme mu nejd°φve nadefinovat, co za nßs mß zobrazit. Tak₧e nap°φklad mß dce°inn² prvek ItemTemplate - v n∞m definujeme zp∙sob zobrazenφ jednΘ polo₧ky v DataTable (pro ka₧d² DataRow bude tento k≤d zobrazen). Je z°ejmΘ, ₧e bude povinn². Podobn² je prvek AlternatingItemTemplate, kter² se ale zobrazuje pro ka₧d² druh² zßznam (urΦen je pokud chcete nap°φklad tvo°it tabulku a ka₧d² druh² °ßdek obarvit r∙znou barvou pro lepÜφ vedenφ oka na ÜirokΘ strßnce). Je z°ejm∞ nepovinn². V SeparatorTemplate defunujeme, co se mß zobrazit mezi jednotliv²mi polo₧kami. V HeaderTemplate co se zobrazφ p°ed prvnφm zßznamem, podobn∞ FooterTemplate za koncem.
A jeÜt∞ jednu v∞c je t°eba v∞d∞t p°ed proΦtenφm p°φkladu - vlastnφ DataBinding se v tomto p°φpad∞ zapφÜe pon∞kud rozdφln∞ od p∙vodnφho zp∙sobu. Za prvΘ musφme intanci objektu Repeater "p°edhodit" do jeho vlastnosti DataSource zdroj dat pro svßzßnφ. Tato vlastnost je typu object a akceptuje objekty, jejich₧ t°φdy majφ implmentovanΘ rozhrnaφ IEnumerable, co₧ v praxi znamenß, ₧e do nφ m∙₧eme vlo₧it datovou tabulku, ale t°eba i pole nebo datov² °ßdek. Za druhΘ si musφme uv∞domit, s Φφm budeme vßzat jednotlivΘ bloky <%# %>. Musφme se zde odvolßvat na blok ve kterΘm se nachßzφme (Container) a jeho vlastnost DataItem, kterß reprezentuje prßv∞ prochßzen² °ßdek dat. Tak tedy:
<script runat="server"> Sub Page_Load() Dim conn As SqlConnection(connString) Dim adap As SqlDataAdapter("SELECT * FROM autor", conn) Dim ds As DataSet = new DataSet() adap.Fill(ds, "autor") rep.DataSource = ds.Tables("autor") DataBind() End Sub </script> <asp:Repeater id="rep" runat="server"> <HeaderTemplate> <table> <tr><td><b>JmΘno autora<td><b>E-mail </HeaderTemplate> <ItemTemplate> <tr style="background-color: white;"><td><%# Container.DataItem("jmeno") %> <td><%# Container.DataItem("mail") %> </ItemTemplate> <AlternatingItemTemplate> <tr style="background-color: #DDDDDD;"><td><%# Container.DataItem("jmeno") %> <td><%# Container.DataItem("mail") %> </AlternatingItemTemplate> <FooterTemplate> </table> </FooterTemplate> </asp:Repeater>
V²stup bude vypadat t°eba takto:
LukßÜ Lßnsk² | lansky@czech-ware.net |
Jakub Kaplan | cskjr148487@seznam.cz |
TomᚠSrb | 148487cskjr@centrum.cz |
Mat∞j èt∞pßnek | csk148487jr@atlas.cz |
Tento p°φstup vßm mo₧nß p°ijde jako pon∞kud t∞₧kopßdn², ve slo₧it∞jÜφch aplikacφch mß vÜak sv∙j p∙vab a opodstatn∞nφ. Mimochodem, podφvßte-li se do dokumentace .NET Frameworku a ve jmennΘm prostrou System.Web.UI.WebControls najdete Repeater, zjistφte, ₧e ItemTemplate a ostatnφ tyto prvky jsou vlastn∞ vlastnosti Repeateru. V n∞jakΘ z p°φÜtφch lekcφ si vysv∞tlφme, jak vytvß°et podobnΘ slo₧itΘ ovlßdacφ prvky - to je velmi p∞knß demonstrace sφly .NETu.
DataList p°edevÜφm zavßdφ dv∞ novΘ Üablony - SelectedItemTemplate pro zobrazenφ polo₧ky vybranΘ u₧ivatelem a EditItemTemplate pro polo₧ku je₧ mß b²t u₧ivatelem zm∞n∞na. To je jeho hlavnφ v²hoda oproti Repeateru, p°esto₧e jsou si tyto dva prvky velmi podobnΘ.
Jak p°edßme ovlßdacφmu prvku zprßvu, ₧e chceme tuto °ßdku zobrazit? Vcelku jednoduÜe - existuje serverov² ovlßdacφ prvek LinkButton, kter² se na klientovi tvß°φ jako klasick² odkaz, m∙₧e vÜak na stran∞ serveru vykonßvat specißlnφ funkce urΦenΘ atributem Command. ZapφÜeme-li do n∞j "Select", DataList tento p°φkaz "odchytne" a poÜle klientovi konkrΘtnφ zßznam v rozbalenΘm tvaru. Podobn∞ fungujφ p°φkazy "Cancel" (zruÜφ rozbalenφ polo₧ky), "Update" (zobrazφ Üablonu EditItemTemplate), "Delete" (odstranφ danou polo₧ku).
Zase tak automatickΘ tyto zm∞ny b²t nemohou, programßtor musφ dostat mo₧nost, jak reagovat na p°φsluÜnΘ udßlosti. Proto mß DataList parametry, do kter²ch m∙₧eme vlo₧it nßzvy obslu₧n²ch metod, kterΘ budou vyvolßny po u₧ivatelov∞ akci.
DalÜφ zajφmavou vlastnostφ je fakt, ₧e u₧ se nemusφme starat o tabulkovou reprezentaci. DataList sßm obsahuje vlastnosti, kterΘ nastavφ v²stup do strßnky bez dlouhΘho psanφ. Jsou to vlastnosti RepeatLayout, kterß umo₧≥uje hodnoty Table (klasickß tabulka) a Flow (beztabulkovΘ uspo°ßdßnφ) a RepeatDirection, kterß mß hodnoty se z°ejm²mi v²znamy Horizontal a Vertical.
Op∞t p°φklad:
<script runat="server"> Sub Page_Load() Dim conn As SqlConnection(connString) Dim adap As SqlDataAdapter("SELECT * FROM autor ORDER BY id", conn) Dim ds As DataSet = new DataSet() adap.Fill(ds, "autor") datl.DataSource = ds.Tables("autor") DataBind() End Sub </script> <asp:DataList id="datl" runat="server" RepeatDirection="Vertical" RepeatLayout="Table" > <ItemTemplate> <asp:LinkButton id="Φudlφk1" runat="server" Text="<%# Container.DataItem("jmeno") %>" CommandName="Edit" /> </ItemTemplate> <SelectedItemTemplate> <%# Container.DataItem("jmeno") %>: <%# Container.DataItem("mail") %>
</SelectedItemTemplate> </asp:Repeater>
Automaticky se vygeneruje seznam autor∙, po kliknutφ na n∞jakΘ jmΘno se zobrazφ mailovß adresa dotyΦnΘho autora.
Na p°φÜtφ dφl si nechßme prßci s upravovßnφm polo₧ek v DataListu. P°edstavφme si takΘ nejkomplexn∞jÜφ serverov² ovlßdacφ prvek pro prßci s daty, DataGridem a prozkoumßme dalÜφ taje databßzovΘ technologie jako jsou transakce a ulo₧enΘ procedury. Vytvo°φme s pomocφ databßzφ takΘ inteligentnφ diskusnφ f≤rum, na kterΘ si procviΦφme vÜechnu doposud probφranou lßtku.
VeÜkerΘ nßm∞ty, dotazy a p°ipomφnky piÜte na adresu lansky@czech-ware.net.