ASP.NET pro zaΦßteΦnφky
8. DataSet a prßce s nφm
MENU
DataSet

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.

Svßzßnφ dat a serverovΘ ovlßdacφ prvky pro prßci s daty

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

Repeater

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 Kaplancskjr148487@seznam.cz
TomᚠSrb148487cskjr@centrum.cz
Mat∞j èt∞pßnekcsk148487jr@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

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.

Zßv∞rem

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.

LukßÜ Lßnsk²
VeÜkerΘ nßm∞ty, dotazy a p°ipomφnky piÜte na adresu lansky@czech-ware.net.