Announcement

Collapse
No announcement yet.

guter Entwurfsstil? Temporäres Erstellen und Löschen in DB

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • guter Entwurfsstil? Temporäres Erstellen und Löschen in DB

    Hallo liebe Entwicklergemeinde,

    ich brauche noch einmal euren gemeinschaftlichen Rat.

    Ich implementiere eine Benutzerverwaltung in einer Businessschicht, wie auch in der Datenschicht. Dabei gibt es in der Businessschicht eine BenutzerCollection, die eine Fabrikmethode zur Konstruktion eines neuen Benutzers enthält. Die BenutzerCollection (IList<Benutzer>) hält im Hintergrund 1 typisiertes Dataset, welches alle Benutzer, die die Collection gerade verwaltet, enthält.

    Wenn jetzt ein neuer Benutzer registriert werden soll, brauche ich eine BenutzerId (Primärschlüssel), um Daten nicht nur in die Haupttabelle (BenutzerDaten) eintragen zu können, sondern eben auch in weiteren Childtabellen. Soweit ich weiß, funktionieren die Get[ChildTabelle]Rows()-Methoden auch nur bei gesetztem Primärschlüssel, wie auch anders.

    Die Registration eines Benutzers kann aber aus Gründen abgebrochen werden. In diesem Fall lösche ich über die Dispose-Methode (in der Benutzer-Klasse) wieder den Benutzer aus der Collection wie auch aus der Datenbank.

    Ist das ein guter Entwurfsstil oder wie würde eine Alternative aussehen? Ich habe mal gelesen, wenn man Daten aus einer Tabelle löschen muss, hat man etwas falsch gemacht. Aber wie komme ich sonst zu einem Primärschlüssel und kann so die GetChildMethoden im Dataset nutzen?

    Viele Grüße

    Andreas Möhlenbrock

  • #2
    Hallo!

    Wahrscheinlich hast Du schon eine Lösung gefunden. Für die Lösung gibt es sicher kein Patentrezept. Früher (zu Delphi-Zeiten) habe ich die Daten selber verwaltet und konnte dann auch bestimmen wie die Daten in die Datenbank eingetragen wurden. Jetzt wo ich den konfort von .net verwende muß man eben abstriche machen.

    Ich habe ähnliche Aufgaben so gelößt, das ich in so einem Fall z.B. den Benuter in einem vorgelagerten Dialog anlege. Alle Felder werden mit Defaultwerte beschrieben. Der Primärschlüssel wird aus der Tabelle gelesen.

    Die Bearbeitung des Benutzers erfolgt nun in einem eigenen Dialog. Zu diesem Zeitpunkt ist der Benuter angelegt. Ein löschen des Benutzers erfolgt NICHT über den Abbruch-Button. Der User muss sich im vorgeschalteten Dialog entscheiden ob er es ernst mit der Erstellung eines neuen Benutzes meint.

    Eine "weitergabe" des Primärschlüssels erfolgt eigentlich nur wenn ein typisiertes DataSet eingesetzt wird in dem auch die Referenzen enthalten sind.

    Das ist jetzt nur meine Lösung - vielleicht nicht die welche Du suchst oder die eleganteste.

    mfg
    Thoma

    Comment


    • #3
      Hallo,

      Thomas, Danke dir für deine Antwort. In der Tat brauche ich im Dataset den Primärschlüssel, um Childtabellen adressieren zu können. Die Frage ist, wie kommt man am geschicktesten zu einem Primärschlüssel?

      Variante 1, wie oben beschrieben:
      Man erstellt einen temporären Benutzer in der Datenbank, den man ggf. wieder löschen muss.

      Variante 2:
      Es wird in der Datenbank zusätzlich eine Tabelle gehalten, die die letzte vergebene BenutzerId anzeigt. Eine Stored-Procedure inkrementiert dieses Feld und gibt die neue BenutzerId zurück. (Besteht hier die Gefahr, dass mehrere Stored-Procedures gleichzeitig den selben Wert inkrementieren?)

      Variante 3:
      Man verwendet GUIDs. Diese sind allerdings wesentlich länger, außerdem besteht das Problem, dass Felder, die abhängig von der BenutzerId sind, wie z.B. die Kundennummer, hier nicht mehr gebildet werden können.

      Ist Variante 2 gebräuchlich?

      Viele Grüße

      Andreas Möhlenbroc

      Comment


      • #4
        Hallo Andreas,

        sicherlich kann man Variante 2 einsetzen, was hälst Du von der Idee ein Benutzerpool einzusetzen. Hier sind dann schon IDs vorhanden die du ganz einfach nutzen kannst. Soetwas wird häufig bei Connectpools verwendet. Das könnte man sich doch zur Nutze machen und Du brauchts keine Daten in der Datenbank löschen.
        Gruß
        SO

        Comment


        • #5
          Hallo zusammen,

          so richtig haben mir alle Varianten nicht gefallen, eine Idee ist mir gekommen, man könnte in einem typisierten Dataset die Relationen NICHT über die Primärschlüssel der Datenbank gestalten, sondern innnerhalb des Datasets eigene LOKALE IDs führen, die nicht mit der Datenbank abgeglichen werden.

          Über diese lokalen Ids kann dann zwischen Child- und Mastertabelle referenziert werden.

          Was haltet ihr von dieser Idee?

          Viele Grüße

          Andreas Möhlenbroc

          Comment


          • #6
            Hallo!

            Eigentlich verstehe ich das Problem nicht.

            Wenn in der DB-Tabelle der Primärschlüssel als Integerfeld mit Identifikationsspezifikation "autoinc" festlegt, so wird dieses von VS2005 erkannt und im DataSet das Feld als "AutoIncrement" gekennzeichnet.

            Wird jetzt ein neuer Datensatz angelegt, so "schätz" VS den neuen Primärschlüssel.

            Beispiel:

            CellaBatchRezeptDataSet.RezeptRow row = _RezeptDS.Rezept.NewRezeptRow();

            // Änderungszeitpunkt
            row.AenderungDT = DateTime.Now;

            _RezeptDS.Rezept.AddRezeptRow(row);

            _RezeptID = row.RezeptID;

            Nach dem einfügen erhät man den "geschätzen" Feldwert.

            Mit diesem Wert kann nun in der Detailtabelle weitere Einträge vorgenommen werden.

            Ist die Tabell nun (am besten in der Datenbank definiert) mit Relationen versehen, so werden beim Update der Mastertabell die durch die Datenbank vorgegebenen ID's ermittelt und sowohl in der Master als auch in der Client-Tabelle ausgetauscht.

            Wichtig ist das man die richtige Updatereihenfolge beachtet. Siehe hierzu:
            <a href="/webx?50@@.4a874f5c">Thomas Sparenberg "Update bei Master/Detail geht nicht! HILFFFFFFEEEE" 06.09.2006 21:09</a>

            Dadurch das die Datenbank die Schlüssel vergibt wird sichergestellt, das (eigentlich) keinen doppelten Schlüssel entstehen kann.

            mfg
            Thoma

            Comment


            • #7
              Hallo Thomas,

              danke dir für deinen sehr interessanten Hinweis. Du hast das Problem auf dem Punkt getroffen. Dann kann ich mein Dispose wieder aufräumen.

              Danke!

              Viele Grüße

              Andreas Möhlenbroc

              Comment

              Working...
              X