ADO.net, DataSet, Access, Selbsthochzählender Primärschlüssel um Tabellen zu verbinden



  • Hallo, ich hoffe, dass ich jetzt nicht ein "Nicht schon wieder!" - Gefühl auslöse, aber ich hatte schon immer Probleme mit der Suche hier. Außerdem mangelt es an präzisen Suchbegriffen (wie man an der Überschrift sieht). Ich weiß noch nicht mal, ob das nun besser hierher oder zu C# passt. Da mein Problem aber in der Datenbank liegt, hab ichs jetzt mal hier hingeschmissen.

    Nun, ich hab hier diese Access2000-Datenbank. Zwei Tabellen, verbunden über einen selbst hochzählenden Primärschlüssel. Und nun arbeite ich über ein DataSet damit. Sind schon mal schlechte Voraussetzungen, ich weiß. Wie gut, dass das (e-)Buch ADO.NET Datenbankprogrammierung von Ralf Westphal diesem Problem ein ganzes Kapitel widmet. Mit Beispielen. Aber es funktioniert leider nicht wirklich:

    Nun, man soll ein Ereignis definieren, das bei jeder Zeile ausgelöst wird, die gerade vom DataSet in die Datenbank geschrieben wird. Und das soll so aussehen:

    protected void OnWerkzeugzeileUpdate(object Sender, OleDbRowUpdatedEventArgs args)
    		{
    			int NeuerIdent = -1;
    				if (args.Status == UpdateStatus.Continue && args.StatementType == StatementType.Insert)
    				{
    					OleDbCommand IdentBekommen = new OleDbCommand("SELECT @@IDENTITY", args.Command.Connection);
    					NeuerIdent = (int)IdentBekommen.ExecuteScalar();
    										args.Row["IndexFeld"] = NeuerIdent;
    				}
    		}
    

    Wenn also beim Übernehmen der Daten die im Datenset stehen der Datenbank eine neue Zeile hinzugefügt werden muss, wird der Primärschlüssel mit dem Wert der @@IDENTITY-Eigenschaft von Access (der nächste vergebene Schlüsselwert) überschrieben. Klappt an sich ja recht gut, aber nicht wenn die Tabelle anfangs leer ist. Denn dann gibts den Schlüsselwert 1, der wird zugewiesen und dabei wird festgestellt, dass der im DataSet schon mal vergeben ist -> Exception, Abbruch. Zähle ich dem Wert von Access versuchsweise einfach 1 dazu, klappts auch nicht. Nun, dass es sonst klappt, verwirrt mich schon sehr. Ich glaube, ich habe mich jetzt irgendwie festgefahren, hat jemand von euch ne Idee?

    Edit: Möglicher Denkfehler... vielleicht dient diese Funktionsweise nur dazu, die Daten im DataSet an die neuen, primärschlüsselaktualisierten Daten in der Datenbank anzupassen... und nicht andersrum. Das würde voraussetzen, dass der beim Schreiben eines neuen Datensatzes im DataSet ermittelte interne Primärschlüssel beim Schreiben in die Datenbank ignoriert und verworfen wird... *grübel*

    Edit2: Nun, wenn ich nun davon ausgehe, dass mein letzter Gedanke stimmt und ich das ganze Geschwurbel mit dem Ereignis für meine Anforderungen überhaupt nicht brauche - warum klappts dann nicht ohne? Die Verbindung zwischen den Tabellen habe ich so hergestellt:

    MagazinWerkzeugAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
    MagazinWerkzeugAdapter.Fill(Set, Vatertabelle);
    MagazinSchneidenAdapter.Fill(Set, Kindtabelle);
    Set.Relations.Add("", Set.Tables["Indexfeld"].Columns[Steuerungsinfo.Schneidenschluessel], Set.Tables[Steuerungsinfo.MagSchnTab].Columns["Indexfeld"], true);
    

    Nun, nachdem ich die Tabellen gefüllt habe und beim "Kindfeld" den Schlüssel der Elterntabelle eingegeben habe, bekomme ich beim Updaten des DataSets die Fehlermeldung (vereinfacht) "Datensatz kann nicht hinzugefügt werden, denn zu jedem Datensatz in der Kindtabelle muss ein Datensatz in der Elterntabelle existieren." Nun, das tut es eigentlich. Diese Exception kommt in dem Moment, in dem ich die hinzugefügten Datensätze übertrage - der letzte Schritt des Update-Vorgangs. (siehe http://support.microsoft.com/?scid=kb;en-us;Q313483, "Update Parent and Child Rows")



  • Hallo, falls das Problem irgendwie mit @@IDENTITY zutun hat, guck dir auch mal SCOPE_IDENTITY() und IDENT_CURRENT() an.

    Muss zugeben, dass ich dein Post nur flüchtig überlesen habe und evtl. is das totaler Schwachsinn, den ich da poste 😉



  • personenkult schrieb:

    evtl. is das totaler Schwachsinn, den ich da poste 😉

    Macht nichts, bei mir ja auch. 😃 Bin ja innerhalb eines Posts in drei verschiedene Richtungen gerannt... 🙂

    Ich glaube nicht, dass es am @@Identity liegt. Weiß aber nicht warum. 😉 Nun, ich hab jetzt die Verbindung der beiden Tabellen im DataSet gekillt und der Child-Tabelle eine neue Spalte gegeben, die die vom DBMS erhaltenen Schlüsselwerte der Haupttabellendatensätze bekommt. Diese werden dann direkt vor dem Schreiben ins Fremdschlüsselfeld kopiert. Klingt umständlich, dämlich und nicht nachvollziehbar - ist es auch. 🤡


Anmelden zum Antworten