Page 1 of 2 1 2 LastLast
Results 1 to 15 of 25

Thread: Van master detail naar join?

  1. #1

    Van master detail naar join?

    Hallo hallo,

    In mijn middleware (KBMmw) applicatie heb ik in principe een standaard master-detail situatie. Nu wil ik tijdens het resolve proces wat logica toevoegen waarvoor ik beide tabellen nodig heb, bijvoorbeeld om bepaalde detail records te skippen op basis van een master record. Nu kom ik er denk ik niet onderuit om de master met de detail tabel te joinen (Het resolven van join is geen probleem in KBMmw). Nu wil ik dat de GUI wel gewoon een master-detail laat zien. Dus voor de schermen moet het zich gedragen als een master-detail, achter de schermen als een join. Hoe krijg ik dit voor elkaar?

    Bij voorbaat dank!

  2. #2
    Silly member NGLN's Avatar
    Join Date
    Aug 2004
    Location
    Werkendam
    Posts
    5,133
    Quote Originally Posted by luigi View Post
    ...bijvoorbeeld om bepaalde detail records te skippen op basis van een master record.
    En dat kan niet met een where-clausule in de query op de detail-tabel? Zo nee, en mocht je inderdaad met één dataset moeten gaan werken, dan kan je toch gewoon weer een nieuwe dataset daarvan trekken?
    (Sender as TNLDUser).Signature := 'Groeten van Albert';

  3. #3
    Ik begrijp nog niet goed wat je probeert te doen Leon.

    Resolven van een join heb je kennelijk al helder, het gebruik van origins doet daar wonderen. Verder kun je op je server ingrijpen op de resolver zelf (OnInsert, OnModify etc). Dat ingrijpen kan vrij diep gaan, waarbij je zelfs de auto gegenereerde sql zelf aan kunt passen. Een alternatief, wat ik zelf nogal eens gebruik is een custom service. Ik stuur dan van de client de changesets (checkpoint in je client tabellen) naar de server en laat die zijn ding doen. Zeker als je messaging transport gebruikt en je client niet hoeft te wachten op resultaat kan die meteen door.

    Je zou ook kunnen kijken of je aan de client kant iets kunt doen om je presentatie anders te maken dan wat je server aanlevert (al hoort dat naar mijn mening wel op de server). Je kbmMWclientdataset component is een afgeleide van kbmMemtable. Daar kun je datasets koppelen met attachdataset, waarbij al die datasets weer hun eigen filters e.d. hebben. Dat kun je mogelijk inzetten voor je presentatie laag. Attachdataset lijkt een beetje op wat clonecursor doet bij een normale clientdataset.

    Hopelijk kun je hier iets mee. Zo niet probeer iets duidelijker te maken wat je wilt, bv door een screendumpje en voorbeeld van de data.

  4. #4
    Heb het een beetje onduidelijk neergezet... Ik wil zowel de master als de detail records kunnen aanpassen/skippen op basis van de te resolven master en/of detail records. Ik heb dus zowel gegevens uit de master als uit de detail nodig voor mijn logica. Volgens mij is de enige manier om dit voor elkaar te krijgen met een join van master met detail of zie ik iets over het hoofd? (Ik wil zoveel mogelijk op de server afhandelen én bij voorkeur alle data in één resolve actie wegschrijven, dus niet eerst insert en dan bijvoorbeeld een update er achteraan)

    Wat in essentie het probleem is van de oplossing die ik bedacht heb, is dat je de master-detail eigenlijk om zeep helpt en er (tijdelijk) een gedenormaliseerde tabel van maakt met redundante gegevens (master). Als ik dus een data-aware component aan deze join hang voor de master gegevens deze voor ieder detail record ingevuld moeten worden. En dat is natuurlijk niet gewenst. Ik wil dus qua GUI wel de voordelen hebben van een master-detail opstelling.

    Ik hoop dat het nu iets duidelijker is.

  5. #5
    Silly member NGLN's Avatar
    Join Date
    Aug 2004
    Location
    Werkendam
    Posts
    5,133
    Ik had jouw vraag wel goed begrepen, maar dat je met die join ook gegevens wilt wegschrijven is nieuw. Dat kan volgens mij niet, dus zit je toch aan aparte updates en evt. reloads vast. Nu weet ik niets van jouw framework af, dus misschien heb ik het verkeerd, anders is post #2 nog steeds van toepassing.
    (Sender as TNLDUser).Signature := 'Groeten van Albert';

  6. #6
    Dat kan volgens mij niet, dus zit je toch aan aparte updates en evt. reloads vast. Nu weet ik niets van jouw framework af, dus misschien heb ik het verkeerd
    in de meeste gevallen zou kbmMW dat wel kunnen door origins te gebruiken. In je server geef je op veld nivo aan uit welke tabel ze komen. De resolver kan daar dan in de meeste gevallen de juiste query uit genereren. Het is echter een situatie die debuggen snel lastig kan maken.

    Leon, er is een kbmMWClientTransactionResolver component die doet wat jij wilt. Doordat je gebruik maakt van kbmMWClientQueries heb je een history van de wijzigingen aan de clientkant (dat is waar de term checkpoint vandaan komt). Dat checkpoint kun je zelf in code beinvloeden als je dat wilt, meestal is de default voldoende. Default staat het checkpoint op het punt waarop je de data ophaalt van de server. Bij een resolve stuur je dan ook alleen de delta's naar de server.

    Waarschijnlijk weet je het al, maar transacties in kbmMW zijn een beetje tricky. Je hebt de transactie binnen kbmMW framework (dus tussen client en server) en de transactie context tussen de server/service en je database. De clienttransaction resolver is van het eerste type. Op je service kun je vervolgens keuzes maken hoe je de context naar de database (of databases) wilt afhandelen.

    In deze link staat een interessant artikel geschreven door Fikret, over dit onderwerp. Mocht je ze nog niet hebben, in de newsgroup (downloads) kun je een hele reeks artikelen downloaden die in Blaise zijn verschenen.

    @Albert, als je eens wilt spelen met kbmMW, er is een gratis download versie (binary only) voor de meeste delphi versies. Via www.Components4developers.com kun je daar info over vinden.

  7. #7
    @Benno

    Als je gebruik maakt van de kbmMWClientTransactionResolver dan vinden er toch op de service alsnog meerdere resolve operaties plaats? Met andere woorden dan kan ik in bijvoorbeeld het onResolveInitialization event nog steeds niet bij de dataset van een andere resolve operatie.

  8. #8
    Nee. Maar volgens mij probeer je dan ook te vroeg in te grijpen in je resolve operatie.

    Ik kan me nog steeds niet helemaal voorstellen wat het probleem nu eigenlijk is. Voor mijn gevoel zou je in moeten grijpen in de onInsert, onUpdate e.d. van de resolver, waarbij je bv gerelateerde data weg kunt schrijven in andere tabellen dan die in je opvraagquery.

    Het kan natuurlijk dat je lastige business logica hebt voor deze tabellen. In dat geval zou ik denk ik kiezen voor een custom service, waarin je de changeset van je clienttabellen heen stuurt. Op je service kun je dan je ding doen op een serverquery en die vervolgens laten resolven. Ik gebruik die constructie bv vaak als ik een boel rekenwerk moet doen aan de serverkant op niet gerelateerde tabellen. Soms gebruik ik dan gewoon een named query die ik open in code, maar ook het gebruik van zelf aangemaakte sql's is dan mogelijk.

  9. #9
    Ik kan me nog steeds niet helemaal voorstellen wat het probleem nu eigenlijk is.
    Het specifieke probleem waar het hier om gaat is mijn ontwerp van partijen(klanten, leveranciers, medewerkers) en hun adres gegevens. Al een tijdje was ik op zoek naar een goede manier om adressen te modelleren, maar ik ben er achter gekomen dat het vrij lastig is om een ontwerp te maken dat én flexibel genoeg is met de vele adres formaten over weg te kunnen én bepaalde adres gegevens zoals postcode, provincie, staat etc. toch op een enigszins gestandaardiseerde manier op te slaan. Uiteindelijk heb ik een ontwerp, voor een gedeelte geïnspireerd door Len Silverstone (Data Model Resource Book), gemaakt dat aan al mijn eisen voldoet.

    In mijn ontwerp worden adressen slechts één keer opgeslagen, ook als er meerdere partijen zijn die van dit adres gebruik maken(adressen verhuizen niet ). In een koppeltabel wordt dan bijgehouden welke partij welk adres heeft met een begin en einddatum. De adres tabel zelf bevat geen velden voor postcode of staat e.d. deze staan samen in een aparte geografische regio tabel. Door middel van een koppeltabel wordt een adres gekoppeld aan geografische regio. De invoer van adressen en geografische regio's wordt gedaan door de eindgebruiker alsof het iedere keer een nieuw adres is. (misschien dat ik wel een soort autocomplete functie inbouw). Als tijdens de invoer (resolve) blijkt dat een adres bijvoorbeeld al bestaat, dan moet het adres zelf niet worden toegevoegd aan de DB maar slechts een verwijzing worden gemaakt naar het reeds bestaande adres. Ook als een geografische regio al bestaat moet deze niet opnieuw worden toegevoegd, maar moet slechts een verwijzing worden toegevoegd. Dit alles moet eigenlijk in één resolve gebeuren.

  10. #10
    maar waarom laat je een gebruiker dan een adres invoeren? Bij een typo is het dan een nieuw adres geworden. Is het dan niet logischer een gebruiker te laten kiezen uit de bekende adressen en alleen indien niet aanwezig een adres in te laten voeren?

    Overigens is je beschrijving volgens mij niet compleet. Je resolver moet altijd een verwijzing toevoegen, alleen bij een nieuw adres moet dat ook worden toegevoegd. Die logica zou ik in de oninsert of onupdate opvangen, waarbij indien nodig een adres wordt toegevoegd.

    Dit is wel een geval waar ik zou twijfelen of ik het clientside oplos (adressen is een stamtabel) of serverside. Maar vrije tekst invoer blijft een uitdaging in het door jou gekozen model.

  11. #11
    maar waarom laat je een gebruiker dan een adres invoeren? Bij een typo is het dan een nieuw adres geworden
    Voor een gedeelte wil ik dit ondervangen door gebruik te maken van google geocoding api om de eindgebruiker een wijziging voor te stellen.

    Uiteindelijk ben je volgens mij toch afhankelijk van de eindgebruiker, tenzij deze geen nieuwe adressen mag invoeren. Maar dat lijkt me ook niet werkbaar in de praktijk. Hoe voorkom jij duplicaten in jouw systeem?


    Overigens is je beschrijving volgens mij niet compleet. Je resolver moet altijd een verwijzing toevoegen, alleen bij een nieuw adres moet dat ook worden toegevoegd. Die logica zou ik in de oninsert of onupdate opvangen, waarbij indien nodig een adres wordt toegevoegd.
    Dat is inderdaad juist!

  12. #12
    Hoe voorkom jij duplicaten in jouw systeem?
    Dat ligt heel erg aan de toepassing. Maar als iets maar 1 keer mag voorkomen (bv een artikel) dan zijn dat bij mij stamtabellen die niet zomaar door iedereen te wijzigen zijn. Uiteindelijk loop je dan nog kans natuurlijk dat 2 mensen eenzelfde artikel maken met net andere schrijfwijze, dus je moet het nog steeds checken en afhandelen. Maar doordat dit een los onderdeel is (edit stamtabel x) hou je het overzichtelijk.

    Adressen zijn bij mij eigenlijk nooit opgeslagen zoals jij dat in jouw datamodel doet. Ik heb meestal een losse adrestabel waar adressen voor een account of contact in kunnen worden opgeslagen. Wel heb ik voor adressen vaak een koppeltabel waardoor ik onder een account meerdere adressen kan hangen met verschillende functies (bv bezoekadres, factuuradres, afleveradres enz). Die adresfuncties zijn dan weer een stamtabel.

    Jouw datamodel is denk ik als je het vanuit ontwerpstandpunt bekijkt beter (verder genormaliseerd), maar ik vraag me vaak af of die moeite opweeegt tegen het extra werk wat je je op je hals haalt. Bij veel van mijn klanten zijn de databases klein. Ik gebruik Firebird als database en als je plaatjes en documenten niet opslaat in de database blijft het compact. Een flinke database is dan nog geen 2GB. Door niet tot het gaatje te normaliseren blijven je joins ook overzichtelijk.

  13. #13
    Ik heb voor dit ontwerp gekozen om makkelijk te kunnen filteren op een bepaald gedeelte van een adres, bijvoorbeeld postcode of staat. En niet zozeer om de database klein te houden. Ik ben het met je eens dat mijn manier veel extra werk en complexiteit met zich meebrengt (wel een goede manier om KbmMw beter te leren kennen ) . Omdat je bijna in ieder administratief systeem te maken krijgt met adressen denk ik dat het de investering wel waard is.

  14. #14
    strak plan. Maar ik zou die adresfunctionaliteit dan los trekken op een losse service, die je via een api kunt benaderen vanaf de andere services.

    Voor je client kun je je data dan nog steeds voorgekookt aanleveren. Je kunt de kbmmemtable variant van een serverside (named query) query gebruiken. Die vul je deels door achterliggende queries en deels door calls naar je adres module. Voor de client blijft alles gelijk, je roept gewoon een named query aan. Deze zijn ook gewoon te resolven, alsof het directe database queries zijn. Ik denk wel dat je op een custom resolver uit gaat komen.

    Door gebruik te maken van een losse adresservice ga je ook optimaler gebruik maken van je cache in de connectionpool, omdat die cache afhankelijk is van de selectsql dus meer variaties heeft bij een join.

    Op de kbmMW university staat een artikel over een datawarehouse met kbmMW. Daarin zie je een mooi voorbeeld van gebruik van de memtable op een service.

  15. #15
    Heb besloten om voor nu een klein stukje logica op de client neer te zetten, volgens mij moet het dan wel lukken. Ik hoop dat ik ooit een ingeving krijg hoe ik dit om een mooiere, maar iets minder complex

    Op de kbmMW university staat een artikel over een datawarehouse met kbmMW. Daarin zie je een mooi voorbeeld van gebruik van de memtable op een service.
    Die ga ik zeker (nog een keer) doornemen! Ik kom iedere keer dat ik een whitepaper doorlees toch weer nieuwe dingen tegen.

Page 1 of 2 1 2 LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •