Announcement

Collapse
No announcement yet.

Löschen einer Zeile aus DataView (RemoveAt)

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

  • Löschen einer Zeile aus DataView (RemoveAt)

    Hallo Andreas und alle zusammen,

    ich habe ein Problem beim Löschen einer Zeile aus einer DataView.
    Ich lösche sie mit RemoveAt(Position) (sie verschwindet auch aus dem Panel und aus der View). Jetzt will ich die Änderung in die Access-DB zurückschreiben und verwende folgende Befehle:
    BindingContext[DataView1].EndCurrentEdit();
    DataSet1 DataSetChanges = new DataSet1();
    DataSetChanges = (DataSet1) DSXYZ.GetChanges();
    if (DataSetChanges != null)
    {
    .
    DataAdapter_Adressen.Update(DataSetChanges.Adresse n);
    .
    }
    Das führt immer zum Fehler:
    "Auf gelöschte Zeileninformationen kann nicht über die Zeile zugegriffen werden."
    Update und Insert neuer Zeilen klappen mit derselben Update-Mimik ohne Fehler.
    Was muss ich beim Löschen noch beachten?
    Vielen Dank für Eure Hilfe!
    Grüße von Rolf

  • #2
    Hallo,

    der Aufruf der Methode <b>Delete</B> entfernt eine DataRow-Objektinstanz <b>nicht</b> aus der DataTable, sondern <b>markiert</b> nur den RowState-Wert als gelöscht. Nur so kann der DataAdapter später aus diesem RowState-Wert eine entsprechende DeleteCommand-Anweisung ausführen. Wenn ein DataRow-Objekt vollständig entfernt werden soll, muss entweder <b>Remove</b> oder <b>RemoveAt</b> bemüht werden. Dann allerdings kann der DataAdapter diesen Vorgang nicht nachvollziehen, da die DataRow-Instanz mit dem RowState bereits vorher aus dem DataSet entfernt wurde.

    &gt;..Fehler: "Auf gelöschte Zeileninformationen kann nicht über die Zeile zugegriffen werden."

    Wenn der Datensatz mit <B>Delete</b> gelöscht wurde, existiert das DataRow-Objekt für diesen Datensatz noch, so dass auch später noch auf dessen Eigenschaften zugriffen werden darf/kann. Wird die DataRow-Instanz jedoch über Remove/RemoveAt physisch vollständig entfernt, provoziert jeder späterer Zugriffsversuch die o.g. Fehlermeldung

    Comment


    • #3
      Hallo Andreas,
      vielen Dank für Deine Antwort. Leider klappt es auch mit Delete() nicht, ich habe alle erdenklichen Spielarten der Delete-Methode ausprobiert - nichts zu machen. Ich habe jetzt nur noch folgende Zeilen im Programm: rowAdressen[1].Delete(); CurrManager.EndCurrentEdit(); DataSet1 DataSetChanges = new DataSet1(); Jetzt habe ich mir mal dieses DataSetChanges angeschaut: Dort ist genau ein Datensatz der Tabelle "Adressen" (aus der ich gelöscht habe) vorhanden. Der RowState dieses Satzes ist "Deleted". Sobald ich aber den Inhalt dieses Satzes anzeigen will (mit einer MessageBox), erscheint wieder obiger Fehler "Auf gelöschte Zeileninformationen kann nicht über Zeile zugegriffen werden.". Nach der Anzeige rufe ich dann die Methode Update() auf, die denselben Fehler liefert. Was habe ich noch falsch gemacht?
      Vielen Dank für Deine Hilfe
      Grüße von Rol

      Comment


      • #4
        Hallo,

        das folgende Beispiel (für eine MS SQL Server-Tabelle in der Datenbank <i>tempdb</i>) verdeutlicht das Prinzip "am Stück":

        a) Struktur der Tabelle (INTEGER-Spalte als Primärschlüssel erhält automatisch vom SQL Server einen fortlaufenden Wert)
        <pre>
        USE tempdb
        GO
        CREATE TABLE MailAdressen (
        RecID INTEGER NOT NULL IDENTITY PRIMARY KEY,
        VName VARCHAR(20) NOT NULL,
        NName VARCHAR(20) NOT NULL,
        eMail VARCHAR(30) NOT NULL,
        Genutzt BIT NOT NULL DEFAULT 0)
        GO
        </pre>
        b) Implementierung des Zugriffs auf diese Tabelle über ein typsisiertes DataSet:
        <pre>
        CurrencyManager aCM;

        private void DoRefreshStatusBar()
        {
        StatusBar1.Text = String.Format("Datensatz {0} von {1}",
        (aCM.Position + 1).ToString(), aCM.Count.ToString());
        }

        private void aCM_PositionChanged(object sender, System.EventArgs e)
        {
        DoRefreshStatusBar();
        }

        private void aCM_ItemChanged(object sender, System.Windows.Forms.ItemChangedEventArgs e)
        {
        DoRefreshStatusBar();
        }

        private void ButtonFill_Click(object sender, System.EventArgs e)
        {
        this.SqlDataAdapter1.Fill(this.dataSet11);
        aCM = (CurrencyManager)this.BindingContext[this.dataSet11, "MailAdressen"];
        aCM.PositionChanged += new EventHandler(aCM_PositionChanged);
        aCM.ItemChanged += new ItemChangedEventHandler(aCM_ItemChanged);
        DoRefreshStatusBar();
        }

        private void ButtonPrev_Click(object sender, System.EventArgs e)
        {
        aCM.Position -= 1;
        }

        private void ButtonNext_Click(object sender, System.EventArgs e)
        {
        aCM.Position += 1;
        }

        private void ButtonNew_Click(object sender, System.EventArgs e)
        {
        aCM.EndCurrentEdit();
        aCM.AddNew();
        }

        private void ButtonUpdate_Click(object sender, System.EventArgs e)
        {
        aCM.EndCurrentEdit();
        SqlDataAdapter1.Update(this.dataSet11, "MailAdressen");
        }

        private void ButtonReject_Click(object sender, System.EventArgs e)
        {
        aCM.EndCurrentEdit();
        this.dataSet11.RejectChanges();
        }

        private void buttonDelete_Click(object sender, System.EventArgs e)
        {
        int iDelPos;
        iDelPos = aCM.Position;
        this.dataSet11.MailAdressen.Rows[iDelPos].Delete();
        this.StatusBar1.Text = iDelPos.ToString();
        }
        </pre>
        Wenn der Button <i>Delete</i> angeklickt wird, ist der aktuell ausgewählte Datensatz unmittelbar darauf beim Browsen "unsichtbar", aber beim <i>Update</i> schickt der SqlDataAdapter trotzdem die DELETE-Anweisung zum SQL-Server, damit der "gelöschte" Datensatz (der in Wirklichkeit nur eine RowState-Markierung als gelöschter Datensatz erhalten hat) tatsächlich im Datenbestand gelöscht wird

        Comment


        • #5
          Hallo,

          Das Löschen (egal ob über Remove oder Delete) funktioniert nicht mehr, sobald in der Table sortiert wird. Weder über BindingManagerBase oder über einen angebundenen DataView ist es mir gelungen einen markierten Satz in einer sortierten Table zu löschen. Mir scheint, als ob BindingManagerBase.Position als auch aCM.Position die aktuelle Zeilennummer ermitteln (erste Zeile = 0, etc. ), Delete dann jedoch die "echte" RowID benutzt.<br>
          Gibts da noch einen Trick?<br>
          Grüße, Danie

          Comment


          • #6
            Hallo,

            &gt;..Gibts da noch einen Trick?

            wenn das DataSet über ein <b>DataView</b> sortiert wird, werden ja auch die Controls an das DataView (aber <b>nicht</b> direkt an das DataSet) gebunden. In diesem Fall muss auch der "richtige" DataRow-Eintrag der DataTable über das DataView als gelöscht markiert werden. Bei mir funktioniert der folgende Weg trotz aktivierer Sortierung:
            <pre>
            <b>private</b> <b>void</b> buttonDelete_Click(<b>object</b> sender, System.EventArgs e)
            {
            <b>string</b> sAdressID = dataViewAdressen[dataGridAutor.CurrentRowIndex][<font color="#9933CC">&quot;AdrID&quot;</font>].ToString();
            <b>if</b> (MessageBox.Show(<font color="#9933CC">&quot;Soll der Datensatz wirklick gelöscht werden?&quot;</font>, <font color="#9933CC">&quot;AdrID: &quot;</font> + sAdressID,
            MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
            dataViewAdressen[dataGridAutor.CurrentRowIndex].Delete();
            DoUpdateDataSetAutor1();
            }
            }
            </pre>
            &#10

            Comment


            • #7
              Hallo Herr Kosch,

              Perfekt. So funktioniert das. Man sollte wahrscheinlich alle Daten, welche zusammengehören in einem DataSet zusammenfassen (LookupDatenmengen etc.), dann aber auch konsequenterweise die Anzeige über einen DataView bündeln. Somit umgeht man auch solche Schwierigkeiten.<br>
              <br>
              Grüße und vielen Dank,<br>
              Daniel Voelke

              Comment

              Working...
              X