ASP.NET

Hierarchien effizient und einfach darstellen

Binden von Daten an geschachtelte Repeater über die Klasse HierarchyList

Zugriffe auf Datenbanken wie SQL-Server oder andere, sollten in jeder Anwendung aufs Nötigste beschränkt werden. Um ein paar Daten zum Beispiel auf eine WebForm zu bringen 3, 4 mal die Datenbank zu konsultieren, bis man alle Daten zusammen hat, ist ineffizient und bedeutet Perfomance-Verlust.

Bei der Anzeige hierarchisch strukturierter Daten wird dieser mehrfache Zugriff jedoch oft in Kauf genommen, um die einzelnen Ebenen getrennt voneinander verarbeiten zu können. In Zeiten von LINQ ist dies eigentlich unnötig, da man hier Daten auch gruppieren kann. Jedoch gibt es auch Alternativen, wenn zum Beispiel der Web-Provider das .NET-Framework 3.5 noch nicht unterstützt oder man die Einarbeitungszeit in LINQ scheut. Auch können LINQ-Statements mit 5 oder 6 Ebenen extrem unübersichtlich werden und somit die Wartbarkeit des Codes verschlechtern.

Die Beispieldaten

Sagen wir mal, es sollen Budgetdaten auf einer WebForm ausgegeben werden und das ensprechende SQL-Statement ermittelt über Joins bereits alle dafür notwendigen Daten aus den beteiligten Tabellen der Datenbank. Die flache Tabelle, ausgegeben in einem Datagrid, könnte somit wie folgt aussehen:

Die einzelnen Employees sollen aber nun mit Ihrem Budgetwert, gruppiert nach dem Monat, ausgegeben werden. Ungefähr so:


Um die Daten in einer solchen Form auszugeben, kann man nun geschachtelte Repeater verwenden, d.h. das ItemTemplate des ersten Repeaters enthält die Ausgabe des Monatsnamens und einen weiteren Repeater zur Ausgabe der Felder Employee und Budget.

Bevor man damit jedoch loslegen kann, müssen die Daten erst in eine Hierarchie gebracht werden, deren Ebenen man an die Repeater binden kann. Hierzu kann man, wie oben erwähnt, entweder LINQ verwenden oder die recht simple Klasse HierarchyList und ihre Unterklassen.

Die Hierarchie-Klassen

Basistechnik der Klasse HierarchyList ist eine generische Liste, die Elemente des Typs HierarchyItem aufnimmt. Jeder Eintrag enthält eine Liste des Typs HierarchyField und ein weiteres Objekt namens SubItems, welches wiederum vom Typ HierarchyList ist. Mit diesem einfachen Konstrukt lassen sich Daten unendlich schachteln.

Die obigen Beispieldaten aus einer DataTable in eine Instanz der Klasse HierarchyList zu füllen ist denkbar einfach:

'Hierarchieliste initialisieren
Dim h As New HierarchyList

For Each dr As DataRow In ds.Tables(0).Rows

    '1. Ebene ablegen
    Dim h1 As HierarchyItem = h.AddItem(dr.Item("Month")) 'Schlüssel
    h1.AddField("L1_Month", dr.Item("Month")) 'Feld

    '2. Ebene ablegen
    Dim h2 As HierarchyItem = h1.Subitems.AddItem(dr.Item("Employee"))
    h2.AddField("L2_Employee", dr.Item("Employee"))
    h2.AddField("L2_Budget", dr.Item("Budget"))

Next

Die geschachtelten Repeater

Der Code der WebForm ist ebenfalls recht simpel:

<asp:Repeater ID="rptLevel1" runat="server">
<ItemTemplate>

   <h2><%#Container.DataItem.Field("L1_Month").Value%></h2>

   <table>
  
      <asp:Repeater ID="rptLevel2" runat="server"
		  DataSource='<%#Container.DataItem.SubItems.Items%>'>
      <ItemTemplate>          

         <tr>
            <td><%#Container.DataItem.Field("L2_Employee").Value%></td>
            <td><%#Container.DataItem.Field("L2_Budget").Value%></td>
         </tr>          

      </ItemTemplate>
      </asp:Repeater>
  
   </table>

</ItemTemplate>
</asp:Repeater>

Hauptaugenmerk liegt dabei auf den beiden ineinander geschachtelten Repeatern und der DataSource-Definition des inneren, denn hier wird lediglich das SubItem-Element des übergeordneten Items gebunden. Dies bedeutet, dass die Bindung des ersten Repeaters ausreicht, um das komplette Konstrukt auszugeben.

Me.rptLevel1.DataSource = h.Items
Me.rptLevel1.DataBind()

Wie man sieht, muss es nicht immer LINQ sein. Auch mit Standard-Generics kommt man schnell, einfach und vor allem übersichtlich ans Ziel.

Happy coding :)

Downloads

HierarchyObject.zip
kick it on dotnet-kicks.de AddThis Trackback-Url...

562 Kommentare bislang...

Dein Kommentar hierzu...


Kommentar-Feed für diesen Beitrag
Gravatare werden unterstützt .:. eMail-Adressen werden nicht veröffentlicht
 

RSS-Feed

Die URL des Standard-Newsfeed von zerbit.de lautet:

http://www.zerbit.de/rssfeed.aspx

Login


 

 

Statistik



kürzlich kommentiert

Artikel 293

  • Datum: 17.09.2009
    Kategorie: ASP.NET
    Zugriffe: 29.443
    Kommentare: 562
    Trackbacks: 0

Letzte Beiträge

Kategorien

Buttons & More

Blog-Roll

Banner Piraten-Partei