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

Thread: Problemen met Append in een NestedDataSet (Delphi Bug?)

  1. #1

    Question Problemen met Append in een NestedDataSet (Delphi Bug in TClientDataSet?)

    Hallo allemaal,

    ik heb het volgende probleem waar ik totaal geen antwoord op heb. Ik heb twee datasets, met elkaar verbonden via een MasterSource. Vervolgens worden de master via een TDataSetProvider beschikbaar gemaakt. Dit betekend dat de Child dus een geneste dataset wordt. Tot zover geen problemen.
    Als ik nu ga proberen een nieuw record toe te voegen dan ontstaat de ellende. Delphi gaat nu namelijk automatisch de primary key van een waarde voorzien (namelijk 1). Bestaat deze waarde al, dan krijg ik dus een 'Key Violation.'
    Ik kan geen enkele manier ontdekken om hieraan te ontkomen. Ook al verander ik na de Append en voor de Post de waarde van deze key, hij blijft hardnekkig er een 1 van maken.
    Ik heb even op het web wat testcode gezet, zodat duidelijk is wat het probleem is:
    http://www.2at.nl/testprojectsource.zip
    Je moet wel even in Delphi de ConnectionString aanpassen zodat de database en de systeemdatabase gevonden kunnen worden. (Bij versies voor Access XP mag de systeemdatabase gewoon leeg gelaten worden!)

    Als iemand dit gedrag wel begrijpt of misschien een workaround ziet, dan hoor ik het graag!

    Bas.

    p.s. Een stap bij stap gids naar de problemen:
    PROBLEEM
    1) Zet je cursor in het tweede grid (en laat het eerste record in het eerste grid actief)
    2) Druk op het pijltje naar beneden (voegt nieuw record toe)
    3) Vul bij naam even een waarde in
    4) Verlaat het record (pijltje omhoog): 'Key Violation'

    INZICHTJE
    1) Ga in het eerste grid naar het laatste record
    2) Zet je cursor in het tweede grid
    3) Maak een nieuw record aan, zoals boven beschreven
    4) Het HandelingsNr is nu 1 (of 2, 3, ...) voor een volgende post.
    Grappig is dat het nu dus goed blijft gaan totdat hij bij 5 aankomt. Die bestaat al: 'Key Violation'.

    Ik kan dit nummer dat hij genereert op geen enkele manier beinvloeden, waardoor ik dus altijd tegen zo'n 'Key Violation' op kan lopen.
    (Verder krijg je de problemen natuurlijk alsnog als je je ClientDataSet applied... Hij zou de boel leeg moeten laten totdat de database met een nummer op de proppen komt... Helaas!)
    Attached Files Attached Files
    Last edited by Bas; 01-Feb-02 at 13:16.

  2. #2
    Nu weet ik weer waarom ik nooit nested datasets gebruik. Het is ook een lastig omdat er wel iets in de key moet worden ingevuld. Het is tenslotte een key en je wilt details aan de master hangen.

    Ik heb het probleem in een eerder project op kunnen lossen door de key van de master te vullen met -1 * RecordCount. OP de server vang ik dat dan weer op door de tijdelijk key te vervangen door de daadwerkelijke key. Die moet dan uiteraard ook aan de details worden toegekend.

    Een tweede oplossing is een method aan de interface van je server toevoegen die een nieuwe key voor de betreffende tabel retourneerd. Deze key zet je dan meteen in het juiste veld in de dataset. Annuleert de gebruiker de actie dan is er een key vergeven die nooit gebruikt zal worden, maar als het goed is is dat geen probleem.
    Marcel

  3. #3
    Helaas is dit niet mijn probleem

    Het probleem dat ik heb is dat je het niet voor elkaar krijgt om in de ClientDataSet een nieuw record te maken (zie eerste post).

    Dat ik bij de ClientDataSet.ApplyUpdates(0) een probleem zou krijgen was ingecalculeerd. Dit gedrag van Delphi begrijp ik echt niet.

    Bas.

  4. #4
    En als je in het AfterInsert event het betreffende veld vult met -1 * RecordCount??

    Ik kan helaas je voorbeeld niet gebruiken, ik krijg een foutmelding op de Acces database.

    Algemene tip: maak je voorbeelden altijd op de databases die door Borland worden meegeleverd in X:\Program Files\Common Files\Borland Shared\Data zodat iedereen ze meteen kan gebruiken.
    Marcel

  5. #5
    Als ik (zelfs handmatig) na het invoegen de waarde van de sleutel verander, dan wordt deze volkomen genegeerd.

    Bas.

  6. #6
    Heel vreemd, dan vraag ik me toch af waar die waarde wordt toegekend. Ik krijg om de één of andere reden nog steeds je Access DB niet geopend (hij zoekt een werkgroepbestand dat ik niet heb), maar ik ga toch nog even zoeken of ik iets kan vinden...
    Marcel

  7. #7
    Het lijkt erop dat er ergens wat indexen en velden door elkaar lopen. Om je voorbeeld te kunnen gebruiken heb ik hem aangepast aan de standaard Borland database en heb ik Customers en Orders aan elkaar gelinkt. Als ik nu in de detailtabel (Orders) een regel toevoeg wordt CustNo gevuld, dat is ook de bedoeling, Orders is tenslotte detail van Customers. Maar uit jouw beschrijving maak ik op dat niet het gelinkte veld wordt gevuld, maar de primary key van de detail tabel.

    Ik zal mijn voorbeeld weer bijsluiten, probeer het hier eens mee.
    Attached Files Attached Files
    Marcel

  8. #8
    Het zit hem inderdaad niet in de foreign key van de child tabel (CustNo in de tabel Orders), maar in de primary key van de child tabel (OrderNo in Orders). In het voorbeeld van jou treedt alleen het probleem niet op, omdat de primary keys geen autonummer velden zijn... Maak maar een Autonummer veld aan in de tabel orders en je zult zien wat ik bedoel...

    Bas.

  9. #9
    Aha! Autonummer velden zijn sowieso een probleem in een n-tier constructie. Stel dat je het allemaal werkend zou krijgen op de client, als je dan alles gaat opslaan gaat Access vrolijk je nieuwe records zitten autonummeren terwijl jij ze ook al een eigen nummer had gegeven. Dan heb je toch geen idee meer wat je dan bij je details moet gaan invullen?
    Marcel

  10. #10
    Nou. Dat valt nog wel te regelen. Bijvoorbeeld als access allemaal positieve nummers gebruikt (wat standaard is), dan zou je zelf bij -1 kunnen beginnen en daarna vrolijk doortellen. Als je dan bij de datasetprovider even bijhoudt wat access van je -1 maakt kun je dat bij elk volgend record ook veranderen en heb je nooit problemen.
    Helaas krijg ik alleen niet de mogelijkheid om die -1 in te stellen, zoals ik al beschreven had.

    Bas.

  11. #11
    Als je op de Table componenten persistent fields aanmaakt kun je één en ander instellen bij de provider options. Daar kun je je provider ook vertellen dat het niet om een autoincrement veld gaat, maar om een gewoon veld. Als je dat dan vervolgens zelf weer afvangt komt het toch weer goed.
    Marcel

  12. #12
    Ik heb geen enkel idee wat je bedoelt met provider options. In ieder geval helpt het niet als ik het field van TAutoIncField in TIntegerField verander. Probeer maar...

    Bas.

  13. #13
    Dat kan ik me voorstellen, ik bedoelde natuurlijk ProviderFlags, een property van het TField object:

    TProviderFlag = (pfInUpdate, pfInWhere, pfInKey, pfHidden);

    Verder zou je ook naar de AutoRefreshFlag kunnen kijken:

    TAutoRefreshFlag = (arNone, arAutoInc, arDefault);
    Marcel

  14. #14
    Eigenlijk zie ik niet zo goed in wat ProviderFlags voor me kunnen betekenen. De AutoGenerateValues property van een Field veranderen haalt helaas ook niets uit.

    Bas.

  15. #15
    Klopt, ik zat fout en bedoelde de AutoGenerateValues. Maar ik denk dat er bijna niets anders op zal zitten dan het autonummer veld te vervangen door een gewoon veld, of geen nested datasets te gebruiken.

    Overigens raad ik sowieso zowel autonummer velden als nested datasets af omdat ze niet flexibel genoeg zijn, maar dat neemt niet weg dat het wel zou moeten kunnen werken.
    Marcel

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
  •