Parallelitätsverletzung

  • VB.NET

Es gibt 33 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Parallelitätsverletzung

    Guten Abend,
    ich hab folgendes Problem (wie es auch schon im Thema steht):
    Beim speichern in ein DataGrid bekomme ich folgende Fehlermeldung:
    "Parallelitätsverletzung: Der UpdateCommand hat sich auf 0 der erwarteten 1 Datensätze ausgewirkt."
    Diese Meldung kommt immer wieder bei folgendem Ablauf:
    - Erstelle ersten Datensatz, fülle ihn & speicher ihn
    - Wiederhole dies noch zwei mal mit weiteren neuen Daten
    - nun möchte ich diese bearbeiten und das dann speichern. wenn ich dann auf Speichern klicke, bekomme ich die Fehlermeldung.
    Die Datensätze haben immer fünf Spalten: "Account","Beginn","Ende","Dauer","Preis".
    Beim Erstellen werden also die ersten beiden Spalten gefüllt und beim bearbeiten die letzten drei.
    Details:

    System.Data.DBConcurrencyException wurde nicht behandelt.
    HResult=-2146232011
    Message=Parallelitätsverletzung: Der UpdateCommand hat sich auf 0 der erwarteten 1 Datensätze ausgewirkt.
    RowCount=1
    Source=System.Data
    StackTrace:
    bei System.Data.Common.DbDataAdapter.UpdatedRowStatusErrors(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, Int32 commandCount)
    bei System.Data.Common.DbDataAdapter.UpdatedRowStatus(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, Int32 commandCount)
    bei System.Data.Common.DbDataAdapter.Update(DataRow[] dataRows, DataTableMapping tableMapping)
    bei System.Data.Common.DbDataAdapter.UpdateFromDataTable(DataTable dataTable, DataTableMapping tableMapping)
    bei System.Data.Common.DbDataAdapter.Update(DataSet dataSet, String srcTable)
    bei Login.Login2DataSet1TableAdapters.DatenTableAdapter.Update(Login2DataSet1 dataSet) in D:\Login2DataSet1.Designer.vb:Zeile 1545.
    bei Login.Form4.ToolStripButton2_Click(Object sender, EventArgs e) in D:\Form4.vb:Zeile 169.
    bei System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
    bei System.Windows.Forms.ToolStripButton.OnClick(EventArgs e)
    bei System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
    bei System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
    bei System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
    bei System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
    bei System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
    bei System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
    bei System.Windows.Forms.Control.WndProc(Message& m)
    bei System.Windows.Forms.ScrollableControl.WndProc(Message& m)
    bei System.Windows.Forms.ToolStrip.WndProc(Message& m)
    bei System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
    bei System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    bei System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    bei System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
    bei System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
    bei System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
    bei System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
    bei System.Windows.Forms.Application.Run(ApplicationContext context)
    bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
    bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
    bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
    bei Login.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:Zeile 81.
    bei System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
    bei System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
    bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
    bei System.Threading.ThreadHelper.ThreadStart_Context(Object state)
    bei System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
    bei System.Threading.ThreadHelper.ThreadStart()
    InnerException:
    Was soll ich da machen?!:o
    Im TableAdapter finde ich nur den CommandText bei FillBy().

    VB.NET-Quellcode

    1. SELECT ID, Nickname, Startzeit, Endzeit, Dauer, Preis, FROM Daten
    Den Datensatz erstell ich mit dem BindingNavigator.Additem & gespeichert wird über:

    VB.NET-Quellcode

    1. Me.Validate()
    2. Me.DatenTableAdapter.Connection.Open()
    3. Me.DatenBindingSource.EndEdit()
    4. Me.DatenTableAdapter.Update(Me.Login2DataSet1)
    5. MsgBox("Daten erfolgreich gespeichert", MsgBoxStyle.Information, "Erfolg")
    6. Me.DatenTableAdapter.Connection.Close()

    Es handelt sich dabei um eine Access-Datenbank mit einem Primärschlüssel auf dem Autowert. Beim Erstellen erscheint in der Spalte des Autowertes komischer weiße jetzt statt einem positiven Wert,
    ein negativer. Also bei den zwei Datensätzen -1 & -2.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Angeless“ ()

    ah ja.
    Das Dataset generiert negative, provisorische Primkeys, die DB generiert positive, endgültige Primkeys.
    Daraus folgt, wenn das Dataset einen datensatz abspeichert, dann muss es den sofort wieder abrufen von der DB, um den von der DB generierten endgültigen Primkey zu erfahren, und bei sich einzupflegen.
    Im einzelnen vorgeturnt ist das hier: Autowerte inserten
    Bei mir sieht der Code jetzt so aus:

    VB.NET-Quellcode

    1. Imports System.Data.OleDb
    2. Namespace Login2DataSetAdapters
    3. Partial Class Login2DataSet
    4. Partial Class DatenDataTable
    5. Partial Public Class DatenTableAdapter
    6. Private _IdentityCommand As New OleDbCommand("SELECT @@IDENTITY")
    7. Private Sub Adapter_RowUpdated(ByVal sender As Object, ByVal e As OleDbRowUpdatedEventArgs) Handles _adapter.RowUpdated
    8. If e.StatementType = StatementType.Insert Then
    9. _IdentityCommand.Connection = e.Command.Connection
    10. _IdentityCommand.Transaction = e.Command.Transaction
    11. e.Row(e.Row.Table.PrimaryKey(0)) = _IdentityCommand.ExecuteScalar()
    12. End If
    13. End Sub
    14. End Class
    15. End Class
    16. End Class
    17. End Namespace
    ...aber ich bekomme immer noch die Meldung:
    "Die Handles-Klausel erfordert eine WithEvents-Variable, die im enthaltenden Typ oder einem seiner Basistypen definiert wird."

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Angeless“ ()

    Da weichst du wohl in irgendeiner Weise von der gegebenen funktionierenden Vorlage ab.

    Sieht mir aus, als habest du die Partiale Klasse falsch eingeschachtelt. Die muss im selben Namespace liegen wie die eigentliche Klasse, sonst wird sie als getrennte Klasse aufgefasst, und hat keinen Zugriff auf die generierten Member.
    U.U. verstehst du nicht, wovon ich fasel, dann recherchiere mal die Funktion des Schlüsselwortes Partial
    Ok, neuer Versuch:

    VB.NET-Quellcode

    1. Imports System.Data.OleDb
    2. Namespace Login2DataSet1Adapters
    3. Partial Public Class DatenTableAdapter
    4. Private _IdentityCommand As New OleDbCommand("SELECT @@IDENTITY")
    5. Private Sub Adapter_RowUpdated(ByVal sender As Object, ByVal e As OleDbRowUpdatedEventArgs) Handles _adapter.RowUpdated
    6. If e.StatementType = StatementType.Insert Then
    7. _IdentityCommand.Connection = e.Command.Connection
    8. _IdentityCommand.Transaction = e.Command.Transaction
    9. e.Row(e.Row.Table.PrimaryKey(0)) = _IdentityCommand.ExecuteScalar()
    10. End If
    11. End Sub
    12. End Class
    13. End Namespace
    14. Partial Public Class Login2DataSet1
    15. End Class
    16. Partial Public Class Login2DataSet1
    17. End Class
    Immer noch der Fehler :/
    Ah ja, jetzt ist die Fehlermeldung verschwunden. Es kommt nicht mehr zu Komplikationen mit dem Autowert, dafür werden aber bei jedem Erstellen eines neuen Datensatzes die zweilen leer gespeichert. Also ich erstelle einen Datensatz, fülle ihn, speicher ihn -> er steht im datagrid. ich erstelle den nächsten -> der erste Datensatz ist gelöscht.
    jo, du bringst erstaunliches zuwege!

    keine Ahnung, ob das neueste Fehlverhalten ühaupt was mittm TableAdapter zu tun hat.
    ich zB verwende eh keine generierten TableAdapter mehr - die sind völlig aufgebläht, und doch recht häufig scheint die Generierung auch zu failen.
    Wenn Datenbank, dann mit DBExtensions, aber noch besser fährt man, wenn man erstmal ohne Db entwickelt, und die DB erst zuletzt hinterlegt, und auch nur, wenn dafür zwingende Gründe vorliegen: Datenbänkerei-Einstieg
    wirklich sonderbar.
    Form2 ist als Startformular eingestellt - aber die Solution enthält überhaupt kein Form2! 8|

    Wie ich schon sagte: vergiss den ganzen TableAdapter-Sch... und lerns richtig: Datenbänkerei-Einstieg
    Und lern vor allem Option Strict On!

    Es ist einfach grotesk, für 2 Datensätze eine 544KB Datenbank zu unterhalten.

    (Und bei 2000 Datensätzen ist das immer noch grotesk)

    Für deine vielen Forms musste auch noch Formübergreifendes Databinding lernen.
    Und dafür musste erstmal lernen, wie man Helper-Projekte einbindet (was ja eh mittelfristig unverzichtbar ist)

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    ok, nun hab ich eine neue Form erstellt, dort ein DataGridView eingebunden und mit einer XML-File verknüpft. Also das speichern und laden funktioniert nun. Aber wie kann ich jetzt einen neuen Datensatz erstellen, außer per Hand in die letzte Zeile des DataGrids zu schreiben und die Daten über Text- und Comboboxen eingeben?