2010. március 21., vasárnap

Silverlight TreeView betöltése Linq 2 SQL táblából

Szeretek Linq 2 SQL-el dolgozni. Egyrészt, mert nagyon könnyen lehet modelleket generáltatni SQL Server adatbázisokból, másrészt, mert nagyon könny a generált osztályokkal dolgozni. Silverlight-os alkalmazások fejlesztésével is foglalkozom. A napokban kipróbáltam az új (2009 novemberi) Silverlight 3 Toolkittel megjelent Business Application Template-et. A sablon segítségével a Linq 2 SQL modellünk mindenféle nehézség nélkül eljuttatható a Silverlight alkalmazásunkig.

Ebben a cikkben röviden leírom, hogy milyen egyszerű egy TreeView feltöltése egy Linq 2 SQL táblából. A példa egy szokványos üzleti esetet mutat be: szervezeti egység entitások betöltése. A példához létrehoztam egy Silverlight Business Application-t:

image

A solution két projektet tartalmaz TreeViewPelda (Silverlight Application), TreeViewPelda.Web (ASP.NET Web Application)

image

Szerver oldal

Először a .Web projektben hoztam létre a szerveroldali komponenseket. Első lépésként egy új adatbázis (App_Data mappába):

image

A következő egyszerű adattáblát hoztam létre:

image

image

A tábla tartalmaz egy azonosítót (SzerverzetiEgysegID), egy a szülőre vonatkozó azonosítót (SzuloID), és néhány adatot. Definiáltunk egy külső kulcsot a SzuloID és a SzervezetiEgysegID összekapcsolására.

Létrehoztam a Model mappába egy Pelda.dbml-t:

image

A dbml layout a következő (nem egy bonyolult…):

image

Kicsit átírtam a kapcsolathoz generált tulajdonságok neveit, mert nem igazán a magyar nyelvhez van kitalálva a generátor… :) Így lett a SzervezetiEgysegs => Gyermekek, SzervezetiEgysegs1 => Szulo

image

Generáltattam egy DomainService osztályt SzervezetiEgysegManagerService néven. Ez az osztály teszi lehetővé a kliensnek az adatelérést. Erre most nem térnék ki. Fontos, hogy mielőtt létrehoznánk az osztályt, fordítsuk le a projektet, mert csak így fogja adatforrásként megtalálni a Linq 2 SQL osztályunkat a varázsló.

 image

Megjelenik a varázsló, amelyben kiválaszthatjuk, hogy mely entitásokhoz kívánunk hozzáférést biztosítani az új Domain Service osztályunkkal.

image

Igazából, ha nem nyúlunk hozzá a generált kódhoz, már akkor is használható, de ez a mixelt magyar/angol helyesírás kicsit idegesítő, ezért én a példában generált GetSzervezetiEgysegs metódusnevet átírtam GetSzervezetiEgysegek-re.

Kliens oldal

Ahhoz, hogy a kliens oldalon használhassuk ezt az újonnan generált osztályt, le kell fordítanunk a Web projektet. Ilyenkor a kliens alkalmazás Generated_Code mappájába generál kódot a template. Ez a solution explorerben nem látszik. Nincs includolva.

A példa egyszerűsége kedvéért a főoldalra (View/Home.xaml) helyeztem el egy TreeView controlt. Általában érdemes a vezérlőket “behúzni” a ToolBox-ról, mert akkor a Visual Studio automatikusan hozzáadja a szükséges névtereket a xaml fájl root-jához. Az alábbi kódot szúrtam be az oldalra:

<controls:TreeView x:Name="tree" 
                   ItemsSource="{Binding Mode=OneWay}">
    <controls:TreeView.ItemTemplate>
        <toolkit:HierarchicalDataTemplate 
            ItemsSource="{Binding Path=Gyermekek}">
            <TextBlock Text="{Binding Path=Nev}" />
        </toolkit:HierarchicalDataTemplate>
    </controls:TreeView.ItemTemplate>
</controls:TreeView>

A TreeView feltöltése nagyon egyszerűvé válik a HierarchicalDataTemplate használtával. Ez a definíció a teljes rekurzív feltöltés megvalósításának feladatát leveszi a vállunkról. A HierarchicalDataTemplate ItemSource tulajdonsága határozza a meg a rekurziót. Az itt kötött tulajdonságnak kell tartalmaznia a gyermekobjektumokat.

Hogy ez a TreeView működjön, a OnNavigatedTo eseményre a következő kódot írtam:

var ctx = new SzervezetiEgysegManagerContext();
var loadOperation = ctx
    .Load<SzervezetiEgyseg>(ctx.GetSzervezetiEgysegekQuery());
loadOperation.Completed += (sender, eargs) =>
{
    if (!loadOperation.HasError)
    {
        tree.ItemsSource = loadOperation.Entities
            .Where(f => f.Szulo == null);
    }
};

A fenti kód egy aszinkron WCF hívást kezdeményez a generált service context segítségével. Ha a hívás sikeresen befejeződik, az anonim delegate eseménykezelő beállítja a TreeView ItemsSource tulajdonságát a visszaadott adatok szűlő nélküli példányainak kollekciójával.

A példához definiáltam egy kis mintaadatot is.

image

Ha így lefuttatjuk az alkalmazást, a következő kimenetet kapjuk:

image

Ez egy igen egyszerű példa. A cél csak a lehetőség bemutatása volt. Remélem van akinek hasznos.

A példakód betöltéséhez Visual Studio 2008 vagy Visual Web Developer 2008 kell. Szükséges még a Silverlight Tools for Visual Studio 2008, továbbá a Silverlight Toolkit (2009 november edition).

Legegyszerűbb a Web Platform Installer használata.

Kapcsolódó anyagok:

Forráskód letöltése

Referenciák:

Microsoft Visual Studio

Silverlight

Silverlight Toolkit

Web Platform Installer

Silverlight Get Started oldal

2010. március 18., csütörtök

Első

Üdvözlöm! Ez az első bejegyzés az új blogomban. Eddig különböző helyeken tettem közzé szakmai tapasztalataimat és megjegyzéseimet. Ezentúl egységesen ezt a blogot fogom használni, amely elérhető a http://hu.martonrusko.com/ címen, míg az angol nyelvű írásaimat a http://martonrusko.com/ címen teszem közzé.

A blog elsősorban informatikai problémákkal foglalkozik. Kiemelten szoftverfejlesztés, üzemeltetés, gyakorlati web-fejlesztési problémák és ezekhez hasonló témákban. Persze, lehet, hogy lesz más is. Előre nem mondanék semmit…

Törekszem rá, hogy olyan érdekes dolgokról írjak, amelyek a napi munkám során előfordulnak és másoknak is tanulságul szolgálhatnak. Alkalmanként előfordulhat, hogy a cikkek a saját véleményemet jelenítik meg egy-egy témában, lehet, hogy nem ért mindenki egyet a taralommal. Tessék kommentálni… :)