Delphi - Multi-tier alkalmazásfejlesztés MIDAS komponensekkel

Multi-tier 5. rész

forráskód letöltése
Ezen a héten a múltkori példánkat folytatjuk és fejlesztjük tovább, két új példát is készítve. A két példában a múlt héten készített szerveralkalmazáshoz kapcsolódunk. Első példa (\DCOMConn02\ könyvtár)

Az adatmodulunkkal készen vagyunk, most nézzük, hogyan tudjuk felhasználni az adatait kliensalkalmazásunk további részeinél.
Adjunk egy új Form-ot a példánkhoz. Szerkesszünk egy TDBGrid és egy TDBNavigator komponens segítségével egy szokványos adatbeviteli Form-ot. A TDBNavigator VisibleButtons tulajdonságánál az nbRefresh-t állítsuk False-ra. Ez azért szükséges, mert a TClientDataSet adatainak frissítése másképp működik, mint a TTable komponensnél, ugyanis a kliensalkalmazásunk TClientDataSet-jébe az adatok a szervertől egy adatcsomag formájában töltődnek le, az eredeti tábla egy részének másolataként, és a kliensgép memóriájában kerülnek tárolásra. Postázáskor tehát csak a helyi adatok módosulnak, így nem lehetséges azok frissítése a szerveren lévő - eredeti - táblában mindaddig, míg meg nem hívjuk a kliens adathalmaz ApplyUpdates metódusát. A módosított adatok szintén adatcsomag formájában ilyenkor "elutaznak" a szerverhez, ahol a változtatások most már valóban megtörténnek az eredeti adattáblában.
A kiiktatott Refresh-gomb helyett az frmFoform OnClose eseményére írtunk egy eseménykezelőt (TfrmFoform.FormClose), amely az ApplyUpdates metódust hívja meg a cdsSzemelyek kliens adathalmaznál. Mivel a cdsJelentkezes detail-táblát beágyaztuk a cdsSzemelyek mastertáblába (cdsJelentkezes tábla DataSetField tulajdonsága), ezért a cdsSzemelyek frissítésekor a beágyazott detail-tábla adatai is frissítésre kerülnek a szerveren. Megfigyelhetjük, hogy a cdsJelentkezes ProviderName és RemoteServer tulajdonságait üresen hagytuk, mivel - beágyazott (nested) táblaként - ezeket a master (cdsSzemelyek) adathalmaz biztosítja a beágyazott adathalmaz számára.

A Form-on lévő TDBGrid komponens tblJelentkezes-nevű oszlopa reprezentálja a beágyazott kliens adathalmazt. Ha erre rákattintunk, és a megjelenő ellipszis gombot megnyomjuk, akkor egy külön rácsban megjelennek az aktuális master-rekordhoz tartozó, beágyazott kliensrekordok a cdsJelentkezes kliens adathalmazból.
Amennyiben új személyt viszünk fel az adatbázisba, a SZEMELYKOD-mezőt nem kell kitöltenünk! (A TDBGrid-ben csak a szemléltetés miatt hagytuk benne.) Ez azért van, mert az SQL-adatbázisunkba beépítettünk egy generátort, amelynek minden értéke új személy adatbázisba való felvitele előtt eggyel növekszik, és értéke lesz az új személykód. Ezt az SQL-adatbázisba szintén beépített trigger vezérli, amely az adatbázis BeforeInsert eseményének bekövetkezésekor fut le. (Ugyanez a trigger esemény írja át a kisbetűvel bevitt NEM-kódot is nagybetűssé.) Ahhoz, hogy az új személy felvitele után a rácsunkban is megjelenjen az így generált személykód, a cdsSzemelyek AfterPost eseményének eseménykezelője meghívja az adathalmaz ApplyUpdates metódusát, valamint lezárja és újra megnyitja az adathalmazt. Ez azért szükséges, hogy a szerverről újra letöltődjenek a kliensalkalmazásba az aktualizált adatok a szerver által legenerált új személykóddal együtt.

A Form-on elhelyeztünk egy TRadioGroup komponenst is. Ez szolgál a cdsSzemelyek kliens adathalmazba letöltött adatok szűrésére. Ennek OnClick eseménykezelőjéből hívtuk meg a cdsSzemelyek kliens-adathalmaz DataRequest metódusát, ami egy szűrő (Filter) kifejezést küld el a szerveralkalmazásnak egy sztring formájában. Ezt az adatkérést a szerveralkalmazás dspSzemelyek nevű providerének (TDataSetProvider) OnDataRequest eseményéhez beírt handler (TPeldaSzerver.dspSzemelyekDataRequest) kezeli le, és a szűrt adatokat visszaküldi a kliensalkalmazásnak (a SZEMELYKOD>0 feltétel érvényesülése esetén minden adatrekord "látszik".)

A beágyazott nézettáblákkal való munka a valóságban - a tapasztalat szerint - kissé körülményes, itt is csak azért említettük meg, mert ez is egy elképzelhető megoldás a master-detail adatkezelésre TClientDataSet-ek esetén. A kényelmesebb, könnyebben kezelhető megoldást nézzük a \DCOMConn03\ könyvtárban!

Második példa (\DCOMConn03\)

Ebben a példában a cdsJelentkezés kliens adathalmaznak is betettünk az adatmodulra egy TDataSource komponenst (dsrJelentkezes), és a cdsJelentkezes-nek beállítottuk a MasterSource és MasterFields tulajdonságait. Így sokkal egyszerűbb a master-detail kapcsolatban lévő két adathalmaz kezelése, mert a nézetrekordok is állandóan látszanak, és a kezelésük és frissítésük is egyszerűbben megoldható.
Ehhez a cdsSzemelyek AfterPost eseménykezelőjéhez (TDM.cdsSzemelyekAfterPost) még adtunk egy sort, amely a cdsJelentkezés adathalmaznak meghívja az ApplyUpdates metódusát. Ez azért szükséges, mert a nézettábla most már nincs beágyazva a master-táblába, így annak ApplyUpdates metódusát meghívva nem frissítődik automatikusan. Ugyanezért figyeljünk arra is, hogy a cdsJelentkezes "PacketRecords"-tulajdonságát feltétlenül állítsuk "-1"-re, mert egyébként a master-rekordokhoz tartozó nézet-rekordok nem töltődnek le a kliensalkalmazásunkba!
Ezért kell az ApplyUpdates metódus paramétereként is megadni a "-1"-et, mert csak ilyenkor kerül vissza az adatbázisba az összes - a kliens adathalmazokban (TClientDataSet) - megváltoztatott rekord! Az adatok kliensalkalmazásba való újratöltéséhez viszont elég csak a cdsSzemelyek DataRequest metódusát meghívni, mert a master-detail kapcsolat miatt a cdsSzemelyek adathalmazban navigálva a szerver leküldi az aktuális master-rekord nézet (detail) rekordjait a cdsJelentkezes kliens adathalmazba. (Paraméterként most csak egy üres sztringet adunk át a szervernek, mert csak újraolvasásról van szó, nem történik szűrés.)




Multi-tier cikksorozat