Announcement

Collapse
No announcement yet.

"Diese Zeile gehört bereits zu einer anderen Tabelle"

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

  • "Diese Zeile gehört bereits zu einer anderen Tabelle"

    Die Aussage ist zwar verständlich, aber ich kann sie nicht nachvollziehen und bitte daher um Mithilfe.

    Ich habe ein Steuerelement das als Masseneingabeformular dienen soll. Beim öffnen des Formulars erzeuge ich mit

    folgender Methode ein DataRow-Objekt:
    Code:
        Public Function CreateEmptyData() As dsReports.ReportsRow
            Dim _dtReports As New dsReports.ReportsDataTable
            Dim _row As dsReports.ReportsRow
    
            _row = _dtReports.NewReportsRow
    
            With _row
                .ReportGUID = ReturnGUID()
                .ReportStatus = ReturnReportStatus()
    
                .Created = Now
                .CreatorGUID = ReturnNullGUID()
                .LastModified = Now
                .ModifierGUID = ReturnNullGUID()
    
                .IsNotVisible = False
                .CanNotDelete = False
    
            End With
    
            Return _row
    
        End Function
    Wenn der Anwender dann auf die Schatfläche SAVE drückt bzw. die Enter-Taste betätigt, dann werden die Werte, die in

    Textboxen und Comboboxen gewählt werden konnten ausgelsen und angepasst und in das dataRowObjekt geschrieben

    Code:
        Private Sub GetFormularData()
    
            With ReportDataRow
                .ReportDay = CDate(ReportsLogicCtl.CalculateLastDayOfMonth(txtReportMonth.Text, txtReportYear.Text) + 
    
    "." + txtReportMonth.Text + "." + txtReportYear.Text)
                .ReportStatus = cboStatus.SelectedValue.ToString
    
    ...
                .ModifierGUID = CurrentUser.UserGUID
                .LastModified = Now
                .CreatorGUID = CurrentUser.UserGUID
    
            End With
    
        End Sub
    Jetzt möchte ich gerne die Daten in die Datenbank schreiben. Wenn ich nun folgenden Weg gehe, dann kommt der besagte

    Fehler, dass die Zeile schon zu einer anderen Tabelle gehört:

    Code:
        Public Function AddReport(ByVal NewReport As dsReports.ReportsRow)
            Dim Success As DBErrorTypes = DBErrorTypes.FAIL
            Dim _adReports As New dsReportsTableAdapters.ReportsTableAdapter
            Dim _dtReports As New dsReports.ReportsDataTable
            Dim _rowCount As Integer = 0
    
            Try
                With _adReports
                    .Connection.ConnectionString = Me.GetConnectionString
                    _dtReports.AddReportsRow(NewReport)
                    _rowCount = _adReports.Update(_dtReports)
                    Success = DBErrorTypes.OK
                End With
    
            Catch ex As Exception
                Throw ex
            End Try
    
            Return Success
        End Function
    Meine Frage daher: Was ist der Grund des Fehlers und wie könnte man das Problem lösen?
    Zuletzt editiert von MyKey0815; 05.06.2010, 13:40.

  • #2
    Hallo,

    ich habe verschiedene Probleme mit deinem Code, kann deshalb den Fehler nicht wirklich erklären. Aber ich kann ein paar Hinweise geben:

    Grundsätzlich gilt: Eine neue DataRow wird erzeugt, mit Standardwerten versehen, dann mit speziellen Werten gefüllt, dann per DataTable.Rows.Add(_row) der Tabelle hinzugefügt. Die Fehlermeldung kommt in diesem Fall dann, wenn keine neue DataRow erzeugt wird, sondern die vorhandene Instanz _row der Tabelle ein zweites Mal hinzugefügt werden soll.

    Deine Code-Auszüge sehen insofern sauber aus. Aber mir kommt dieses komisch vor:
    1. Du sagst nicht, wann CreateEmptyData() aufgerufen wird und wie der Rückgabewert benutzt wird.
    2. Woher kommt ReportDataRow in GetFormularData()?
    3. Wozu dienen _adServiceReports und _dtServiceReports in AddReport()? Ich sehe darin keinen Sinn.
    4. Woher kommt NewReport in AddReport()?

    Mein Verdacht ist, dass irgendwo zwischen 1 und 4 keine neue DataRow erzeugt bzw. verwendet wird, sondern die vorherige zusätzlich gespeichert werden soll; und das geht natürlich nicht.

    Ich setze mal voraus, dass du TableAdapter-Methoden und -Namen korrekt verwendet werden. (Mit diesem Datenmonster kann und will ich nicht arbeiten.)

    Gruß Jürgen

    PS. Grundsätzlich gehören Fragen zu Datenbanken ins Unterforum ADO.NET. Ich lasse die Diskussion ausnahmsweise hier stehen, weil zuviele Spezialitäten zu VB (with) und VS (TableAdapter) verwendet werden.
    Zuletzt editiert von Jürgen Thomas; 05.06.2010, 12:43. Reason: PS hinzugefügt.

    Comment


    • #3
      Originally posted by Jürgen Thomas View Post
      Deine Code-Auszüge sehen insofern sauber aus. Aber mir kommt dieses komisch vor:
      1. Du sagst nicht, wann CreateEmptyData() aufgerufen wird und wie der Rückgabewert benutzt wird.
      wenn ich das Formular öffne rufe ich die Funktion CreateEmptyData auf und gebe das Ergebnis in eine lokale Variabel mit dem Namen "ReportData"

      Originally posted by Jürgen Thomas View Post
      2. Woher kommt ReportDataRow in GetFormularData()?
      Diese Methode wird aufgerufen und als Parameter übergebe ich die Variable "ReportData"

      Originally posted by Jürgen Thomas View Post
      3. Wozu dienen _adServiceReports und _dtServiceReports in AddReport()? Ich sehe darin keinen Sinn.
      Waren nur Schreibfehler - Sorry, dass ich dadurch für Verwirrung gesorgt habe

      Originally posted by Jürgen Thomas View Post
      4. Woher kommt NewReport in AddReport()?
      Auch durch Aufruf und Übergabe des ReportData-Variabel

      Originally posted by Jürgen Thomas View Post
      Grundsätzlich gilt: Eine neue DataRow wird erzeugt, mit Standardwerten versehen, dann mit speziellen Werten gefüllt, dann per DataTable.Rows.Add(_row) der Tabelle hinzugefügt. Die Fehlermeldung kommt in diesem Fall dann, wenn keine neue DataRow erzeugt wird, sondern die vorhandene Instanz _row der Tabelle ein zweites Mal hinzugefügt werden soll.
      Bedeutet dass, man kann ein Row-Objekt nicht loslösen? Ich muss also Adapter und DataTable immer als lokale Variabeln definieren?

      Ich wollte halt damit nur erreichen, dass ich ein Objekt erzeuge, dass die Default-Werte übernimmt. Dies Default-Werte sollen dann die entsprechenden Textboxen/Comboboxen mit Werten füllen. Wenn ich dann das Formular schließe, ohne was zu speichern, dann soll das Objekt wieder "verfallen".

      Wie gesagt, es geht hier um ein Masseneingabeformular. Also man soll nicht zu Beginn der Eingabe eine Tast drücken müssen (so wäre es ja in Verbindung mit dem Navigator-Element). Sondern es sollen nur Werte eingetippt werden und über die Enter-Taste in der DB gespeichert werden
      Zuletzt editiert von Jürgen Thomas; 05.06.2010, 17:24. Reason: Zwei Beiträge kurz hintereinander muss nicht sein (solange niemand anderes etwas schreibt).

      Comment


      • #4
        Originally posted by MyKey0815 View Post
        Bedeutet dass, man kann ein Row-Objekt nicht loslösen?
        Naja, es geht schon, macht aber fast niemals Sinn. Dein Fehler liegt darin, dass du ein und dasselbe Objekt wiederholt für verschiedene Dinge benutzen willst und mehrfach in der DataTable hinzufügen willst. Das geht nicht!

        Lösung: Du kannst die ReportData-Variable natürlich am Anfang deklarieren. Du solltest aber eine Instanz immer nur bei Bedarf erzeugen und dann diese Instanz benutzen.

        Ich muss also Adapter und DataTable immer als lokale Variabeln definieren?
        Nein, das hat mit dem Problem überhaupt nichts zu tun. Vor allem die DataTable existiert solange, wie sie eben benötigt wird. Der Adapter und vor allem die Connection sollten aber wirklich nur bei Bedarf erzeugt werden und am besten in einen Using-Block gekapselt werden.

        Wenn ich dann das Formular schließe, ohne was zu speichern, dann soll das Objekt wieder "verfallen".
        Dann ist es sowieso weg (jedenfalls wenn es innerhalb dieses Formulars deklariert und von dort aus erzeugt worden ist).

        Also man soll nicht zu Beginn der Eingabe eine Tast drücken müssen (so wäre es ja in Verbindung mit dem Navigator-Element). Sondern es sollen nur Werte eingetippt werden und über die Enter-Taste in der DB gespeichert werden
        Ob das nun durch eine Taste ausgelöst wird oder durch dich als Programmierer, ist zweitrangig. Auch du weißt ja, unter welchen Umständen ein solches Objekt benötigt wird, und kannst es zielgerichtet erstellen und dabei mit den Default-Werten versehen.

        Gruß Jürgen

        Comment


        • #5
          Originally posted by Jürgen Thomas View Post
          Lösung: Du kannst die ReportData-Variable natürlich am Anfang deklarieren. Du solltest aber eine Instanz immer nur bei Bedarf erzeugen und dann diese Instanz benutzen.
          Danke Jürgen - das hat mir sehr geholfen. War wohl zuviel Sonne, dass ich nicht selber drauf kam

          Dir noch eine schönes WE

          Gruß
          Michael

          Comment

          Working...
          X