Announcement

Collapse
No announcement yet.

Dataset und/oder Datarow nachladen

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

  • Dataset und/oder Datarow nachladen

    Hallo,

    ich lade Daten von einem SQL-Server über einen SqlDataAdapter in eine DataTable die sich ich in einem Dataset befindet. Die Daten werden auf eine eigene Objektklasse abgebildet und sind über einen Treeviewbzw. einen Detaildialog sichtbar.

    Jetzt möchte ich, wenn der Benutzer die Daten editieren will (dies ist sowieso immer nur "zeilenweise" möglich) diese Datenzeile aus der Datenbank nachladen um so zu verhindern dass alte Daten (ein anderen Benutzer kann diese ja geändert haben) angezeigt werden und beim Speichern über der Dataadapter die Parallelitätsverletzung ausgelöst wird.

    Ich habe dazu versucht über das Fill-Kommando des DataAdapter einfach mal alle Daten nachzuladen, allerdings funktioniert dies nicht wirklich. Es kommen immer nur die bisherigen Daten rein, obwohl ich in der entsprechenden Datenbankzeile Werte (über Access direkt) geändert habe.

    Fragen: 1) Kann man eine Datenbankzeile (Datarow) gezielt nachladen oder muss man immer das Dataset aktualisieren? 2) Wie stelle ich es an dass das Dataset nach dem Ausführen den Fill-Kommandos auf den Dataadapter wirklich aktualisiert wird?


    Grüße und Danke,
    Marc

  • #2
    Originally posted by marc.bastian View Post
    1) Kann man eine Datenbankzeile (Datarow) gezielt nachladen oder muss man immer das Dataset aktualisieren?
    Wenn Du die DataRow exakt identifizieren kannst (z.B. durch eine ID), dann kannst Du mit einem passenden Select-Befehl natürlich auch diese eine Datenzeile abrufen. Durch den Fill-Befehl sollte sie zunächst in einer neuen DataTable landen.
    Originally posted by marc.bastian View Post
    2) Wie stelle ich es an dass das Dataset nach dem Ausführen den Fill-Kommandos auf den Dataadapter wirklich aktualisiert wird?
    Die neue DataTable wird per Merge in die vorhandene eingepflegt; wegen der ID wird dabei die vorhandene DataRow durch die neue DataRow überschrieben.

    Das sollte Dir helfen. Jürgen

    Comment


    • #3
      Hallo Marc,

      hast Du Dir schon mal überlegt, was Du machst, wenn ein andere Benutzer den entsprechenden Datensatz gelöscht hat? Was wäre Dein Lösungsansatz in dieser Situation. Gibt es eine Möglichkeit so etwas zu lösen. Wie sieht es mit Locking aus? Was wäre die Lösung, wenn man ein andere Benutzer den Datensatz zur gleichen Zeit bearbeiten möchte, die Änderungen aber noch nicht gespeichert wurden.

      Zu diesem ganzen kann ich Dir einen O/R Mapper empfehlen, auch wenn es nicht der Grundgedanke Deiner Frage ist. Ein O/R Mapper löst solche Probleme in manchen Fällen. Da dort mit Objekten gearbeitet wird, kann man innerhalb einer Liste das entsprechende Objekt in jedem Fall überschreiben, indem die Daten anhand eines Datensatzes neu aus der Datenbank geladen. Somit braucht nichts gemerged zu werden, denn das Objekt ist bereits in der Liste enhalten und bekommt aktuellere Werte zugewiesen.

      Ein O/R Mapper der das in jedem Fall kann ist http://www.invist.net.

      Ein Dataset ist vielleicht eine schnelle Lösung, doch, wie ich finde, viel zu unfexibel, wenn es um solche Problem wie konkurierendes Arbeiten, bzw. bei Zugriff mehrerer Personen auf die gleichen Daten zum gleichen Zeitpunkt.
      Gruss

      Mirko

      Mappen statt hacken mit dem .NET O/R Mapper Invist

      Comment


      • #4
        Originally posted by Jürgen Thomas View Post
        Wenn Du die DataRow exakt identifizieren kannst (z.B. durch eine ID), dann kannst Du mit einem passenden Select-Befehl natürlich auch diese eine Datenzeile abrufen. Durch den Fill-Befehl sollte sie zunächst in einer neuen DataTable landen.

        Die neue DataTable wird per Merge in die vorhandene eingepflegt; wegen der ID wird dabei die vorhandene DataRow durch die neue DataRow überschrieben.
        Hallo Jürgen,

        Danke für deine Antwort. Aber genau da liegt bei mir momentan der Hund begraben. Ich lade nun diese eine Zeile über einen neuen Adapter in in neues Dataset. Dann versuche ich mit "OriginalDataset.Merge(NeuesDataset)" diese eine Zeile zu übernehmen. Leider immer ohne Erfolg. Wenn ich ins neue Dataset reinschaue (einfach per debug.writeln -> Table -> Row -> Item) sehe ich auf einem bestimmten Feld den neuen Wert, nach dem merge ist aber im alten Dataset weiterhin der alte Wert sichtbar.


        Grüße,
        Marc

        Comment


        • #5
          Originally posted by mirkom76 View Post
          Hallo Marc,

          hast Du Dir schon mal überlegt, was Du machst, wenn ein andere Benutzer den entsprechenden Datensatz gelöscht hat? Was wäre Dein Lösungsansatz in dieser Situation. Gibt es eine Möglichkeit so etwas zu lösen. Wie sieht es mit Locking aus? Was wäre die Lösung, wenn man ein andere Benutzer den Datensatz zur gleichen Zeit bearbeiten möchte, die Änderungen aber noch nicht gespeichert wurden.

          Zu diesem ganzen kann ich Dir einen O/R Mapper empfehlen, auch wenn es nicht der Grundgedanke Deiner Frage ist. Ein O/R Mapper löst solche Probleme in manchen Fällen. Da dort mit Objekten gearbeitet wird, kann man innerhalb einer Liste das entsprechende Objekt in jedem Fall überschreiben, indem die Daten anhand eines Datensatzes neu aus der Datenbank geladen. Somit braucht nichts gemerged zu werden, denn das Objekt ist bereits in der Liste enhalten und bekommt aktuellere Werte zugewiesen.

          Ein O/R Mapper der das in jedem Fall kann ist http://www.invist.net.

          Ein Dataset ist vielleicht eine schnelle Lösung, doch, wie ich finde, viel zu unfexibel, wenn es um solche Problem wie konkurierendes Arbeiten, bzw. bei Zugriff mehrerer Personen auf die gleichen Daten zum gleichen Zeitpunkt.
          Hallo Mirko,
          Danke für deine Antwort. Ich habe das nicht explizit erwähnt, aber das mehrfache Editieren wird über eine Datensatzsperre (über eine weitere "Sperrtabelle") geregelt und ist nicht zulässig. Es kann natürlich aber vorkommen dass ein Datensatz geändert wird und dann von einem anderen Benutzer nicht mehr geändert werden kann bevor er nachgeladen wurde.
          Auch wird es in meinem Fall kein Löschen geben, es werden nur Datensätze geändert oder erstellt.


          Grüße,
          Marc

          Comment


          • #6
            Hallo Marc,

            musst Du die Rows denn wirklich mergen? Ist es nicht einfacher, ween Du den Index der DataRow innerhalb der Tabelle ermittelst und anschlisssend die neue DataRow genau diesen Index zuweist? So brächtest Du nichts zu mergen.
            Gruss

            Mirko

            Mappen statt hacken mit dem .NET O/R Mapper Invist

            Comment


            • #7
              Hallo Mirko,
              wenn ich per Dataset -> Table.Rows.Find(key) auf eine Zeile zugreifen will wird folgende Exception ausgelöst: MissingPrimaryKeyException: "Die Tabelle hat keine Primärschlüssel". Das würde vorerst erklären weshalb kein Merge funktioniert. Allerdings hat die Tabelle garantiert einen Primärschlüssel! Wo könnte denn der Fehler liegen?

              Grüße,
              Marc

              Comment


              • #8
                Originally posted by marc.bastian View Post
                ... MissingPrimaryKeyException: "Die Tabelle hat keine Primärschlüssel". Das würde vorerst erklären weshalb kein Merge funktioniert. Allerdings hat die Tabelle garantiert einen Primärschlüssel! Wo könnte denn der Fehler liegen?
                Wird das Feld mit dem PrimaryKey denn im Select-Befehl angesprochen und übertragen? Jürgen

                Comment


                • #9
                  Originally posted by Jürgen Thomas View Post
                  Wird das Feld mit dem PrimaryKey denn im Select-Befehl angesprochen und übertragen? Jürgen
                  Hallo Jürgen,

                  ja, denke schon. Ich mache einen "SELECT * FROM ...". Es wird sogar intern auf die gemappte Klasse als Property übertragen. D.h. das Feld gibt es auf jeden Fall. Nur weiß die Tabelle, warum auch immer, nicht dass es sich um den PrimaryKey handelt


                  Grüße,
                  Marc

                  Comment


                  • #10
                    Ooops, hab's gefunden unter http://support.microsoft.com/kb/305561/en-us. Ich muss dem Adapter explizit mitteilen dass er auch das Schema laden soll:
                    da.FillSchema(ds, SchemaType.Mapped, "Employee")
                    Jetzt klappts auch mit dem Merge problemlos ...

                    Grüße,
                    Marc

                    Comment

                    Working...
                    X