Announcement

Collapse
No announcement yet.

Verwaltung mehrerer Business-Instanzen über ein typisiertes Dataset

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

  • Verwaltung mehrerer Business-Instanzen über ein typisiertes Dataset

    Hallo liebe Entwickler-Gemeinde, hallo Herr Kosch,

    meine Frage beschäftigt sich mit dem Update eines typisierten Datasets auf Datarow-Ebene.

    Eine Suche liefert eine Menge von Benutzern in Form eines typisierten BenutzerDatasets. Der Zugriff auf einen einzelnen Benutzer erfolgt über die Business-Klasse Benutzer und der Übergabe des Datasets samt BenutzerId im Konstruktor.

    Wenn ein Detail von einem Benutzer geändert werden soll, muss ich bisher ein Update (BenutzerTabellenAdapter.Fill) auf der kompletten BenutzerTabelle des Datasets fahren. Das bedeutet, dass mögliche Änderungen weiterer Benutzerinstanzen in diesem Augenblick mit in die Datenbank geschrieben werden, da das Dataset ja weitere Benutzer enthält.

    Kann man ein Update auf einer Zeile veranlassen, welches zusätzlich automatisch die mit dieser Zeile über ein Fremdschlüssel weiterverknüpfte Tabellen aktualisiert?

    Viele Grüße

    Andreas

  • #2
    Hallo,
    wenn mit ADO.NET 2.0 ein typisiertes DataSet erzeugt wird, können die <i>DBDirect</i>-Methoden (im <i>TableAdapter Configuration Wizard</i> über die Checkbox oder im Properties-Editor über die Eigenschaft <i>GenerateDBDirectMethods</i>) automatisch mit angelegt werden. Wenn dann der Anwender in einer Datenmenge nur einen Datensatz ändert, steht nun ein gegenüber der <i>Update</i>-Methode alternativer Aufrufweg zur Verfügung, um den geänderten Datensatz zurück in die Datenbank zu schreiben. Die <i>DBDirect</i>-Methoden <i>Insert, Update</i> (überladene Fassung) und <i>Delete</i> schreiben generell nur einen Datensatz zurück.
    Wenn danach die Datenmenge auf den aktuellen Stand gebracht werden soll (d.h. es sollen auch die in der Zwischenzeit von anderen Benutzern geänderten Daten sichtbar werden), kann der TableAdapeter eine zweite DataSet-Instanz abfordern, die dann über die <i>Merge</i>-Methode in das DataSet der Benutzeroberfläche eingemischt wird. Die Änderungen im DataSet, die bis dahin noch nicht in die Datenbank zurückgeschrieben wurden, werden durch den Merge-Vorgang nicht überschrieben. Alternativ zu <i>Merge</i> steht die erweiterte DataTable-Methode <i>Load</i> zur Verfügung, die über den neuen <i>LoadOption</i>-Parameter <i>PreserveChanges</i> das gleiche Ergebnis erzielt.

    Auch in ADO.NET 2.0 steuert das typisierte DataSet das Master-/Detail-Verhalten nicht automatisch, so dass an dieser Stelle das gleiche Prinzip wie bei ADO.NET 1.x gilt. Je nach der Datenbank (kaskadierendes Verhalten der referenziellen Integrität) und dem Zugriffsweg (Stored Procedure, die alles intern regelt) unterscheidet sich die notwendige Implementierung.

    Comment


    • #3
      Hallo Herr Kosch,

      vielen Dank für Ihre sehr schnelle Antwort. Der Tipp mit dem Merge ist sehr gut. Manches ist mir aber nachwievor nicht klar.

      Ich verwende in der Tat ein typisiertes ADO.Net 2.0 Dataset, welches ich aus dem Server Explorer heraus erstellt habe. In den Eigenschaften des TableAdapters einer Tabelle kann man Select-, Delete-, Insert- und eben auch ein Update-Kommando hinterlegen (lassen). Ich nehme an, dass Sie bei diesen Methoden von den GenerateDBDirectMethods sprechen.

      Der Aufruf eines solchen (Update-) Kommandos erscheint mir nur über die Update-Methode des TableAdapters möglich, die 5 mal überladen ist, eine Überladung stellt eine Methode mit zig Parametern bereit, soviele Parameter, wie meine Benutzer-Tabelle Spalten hat. Ist diese Methode der Angriffspunkt, um gezielt eine Benutzertabellen-Zeile updaten zu können, muss ich dieser Methode jedes Attribut meiner Tabelle übergeben? *stöhn* ;-) Für ein Update könnte ja die Übergabe des Primärschlüssels reichen, wo die restlichen Daten stehen, müsste das Dataset doch wissen.

      Habe ich Sie richtig verstanden, dass es keine vorgefertigte bzw. einfache Möglichkeit gibt, mit einem Update einer BenutzerTabellenZeile weitere Tabellen zu aktualisieren? Im typisierten Dataset gibt es eine wunderschöne Möglichkeit des AcceptChanges, welches auf mehereren Ebenen arbeitet und auch die Tabellenbeziehungen berücksichtigt. Eine solche Methode würde ich mir für den Datenbankzugriff wünschen.

      Viele Grüße

      Andreas Möhlenbroc

      Comment


      • #4
        Hallo,

        &gt;.. muss ich dieser Methode jedes Attribut meiner Tabelle übergeben? *stöhn* ;-)

        Nein - denn die 1. überladene Fassung akzeptiert eine <b>DataRow</b>-Instanz, so dass ein einziger Parameter für den <b>Update</b>-Aufruf ausreicht. Das typsierte DataSet stellt automatisch die <i>FindByXyz</i>-Methode zur Suche nach dem Primärschlüssel bereit, so dass die DataRow-Instanz selektiert werden kann, die gändert werden muss (bzw. die geändert wurde):

        <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border-top: windowtext 1pt solid; padding-top: 0pt; border-left: windowtext 1pt solid; padding-left: 0pt; border-right: windowtext 1pt solid; padding-right: 0pt; border-bottom: windowtext 1pt solid; padding-bottom: 0pt;"><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: teal;">tempdbDataSet</span>.<span style="color: teal;">TestTblRow</span> aRow = tempdbDataSet.TestTbl.FindByid(1);</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; aRow.wert1 = <span style="color: maroon;">"XXX"</span>;</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">int</span> i = testTblTableAdapter.Update(aRow);</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; listBoxLog.Items.Add(<span style="color: teal;">String</span>.Format(<span style="color: maroon;">"Update: {0} Datensatz betroffen"</span>, i));</p></div>

        Das Problem bei den Master-/Details-Updates liegt darin, dass es auf der Seite des typisierten DataSets (TableAdapters) keinen in <b>jeder</b> Situation <b>verlässlichen</b> Weg gibt, der sich automatisch (bereits zur Entwicklungszeit) festlegen lässt. Es gibt Implementierungsbeispiele, die zur Laufzeit die Reihenfolge der Aufrufe (getrennt nach INSERT, UPDATE und DELETE) automatisch ermitteln, aber dies führt jedes Mal zu intensiven Abfragen der Systemtabellen (Schema) der Datenbank (analog zum <i>SqlCommandBuilder</i>). Der momentane "richtige" Weg besteht darin, über die <i>partial class</i> des TableAdapters eine eigene Methode nachzurüsten, in der die zur Datenbank passende Reihenfolge zur Entwicklungszeit einmalig selbst definiert wird

        Comment


        • #5
          Hallo Herr Kosch,

          haben Sie vielen Dank für Ihre schnellen und treffenden Antworten. Der "richtige" Weg ist damit wieder ein gutes Stück klarer geworden.

          Vielen Dank und viele Grüße

          Andreas Möhlenbroc

          Comment

          Working...
          X