mysql_insert_id bei typisiertem DataSet?

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 81 Antworten in diesem Thema. Der letzte Beitrag () ist von 100Volt.

    Mir scheint, das typisierte am typisierten Dataset ist dir bisher entgangen. Paar Beispiele:

    VB.NET-Quellcode

    1. strVorname = Dts.tblKunden.Rows(0).Item(Dts.tblKunden.VornameColumn)
    2. strNachname = Dts.tblKunden.Rows(0).Item(Dts.tblKunden.NachnameColumn)
    muss heissen:

    VB.NET-Quellcode

    1. strVorname = Dts.tblKunden.Rows(0).Vorname
    2. strNachname = Dts.tblKunden.Rows(0).Nachname
    oder noch besser:

    VB.NET-Quellcode

    1. dim rwKunde = Dts.tblKunden.Rows(0)
    2. strVorname = rwKunde.Vorname
    3. strNachname = rwKunde.Nachname


    Dieses hier:

    VB.NET-Quellcode

    1. Dts.tblKunden.Rows(0).Item(Dts.tblKunden.VornameColumn) = strVorname
    2. Dts.tblKunden.Rows(0).Item(Dts.tblKunden.NachnameColumn) = strNachname
    muss dann logischerweise so:

    VB.NET-Quellcode

    1. dim rwKunde = Dts.tblKunden.Rows(0)
    2. rwKunde.Vorname = strVorname
    3. rwKunde.Nachname = strNachname



    Jenes:

    VB.NET-Quellcode

    1. Dim row = Dts.tblKunden.NewtblKundenRow()
    2. row.Vorname = strVorname
    3. row.Nachname = strNachname
    4. Dts.tblKunden.AddtblKundenRow(row)
    wäre besser so:

    VB.NET-Quellcode

    1. Dim row = Dts.tblKunden.AddtblKundenRow(strVorname, strNachname)


    Wenn du erkennst, dass meine Code-Vorschläge Verbesserungen darstellen, und wenn du an einer systematischen Darstellung der Hintergründe und Prinzipien interessiert bist, könnte ich ein 3-teiliges Tutorial (auf englisch) verlinken.

    Ich könnte auch auf deine anderen Fragen eingehen, aber ich mache zu 90% schlechte Erfahrungen damit, wenn ich mehrere Themen im selben Post anspreche.

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

    ... das wollten wir doch Samstag durchkauen. Gestern haben wir ja erstmal das DataSet an's laufen gebracht.
    Wie man dann wo an die Daten rankommt und diese verarbeitet wollte ich dir auch Samstag zeigen.
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:
    Es kommt nun zu einem Fehler beim Anlegen der TableAdapter, so wie es aussieht.

    In dsMain.Logic.vb:

    VB.NET-Quellcode

    1. Imports System.Data.Common
    2. Partial Class dsMain
    3. Public Shared ReadOnly Dts As dsMain
    4. Public _Persistance As MySqlServerPersistance
    5. Private _sCon As String = Nothing
    6. Shared Sub New()
    7. Dim server = My.Settings.DB_Server
    8. Dim UID = My.Settings.DB_Benutzer
    9. Dim passwd = My.Settings.DB_Passwort
    10. Dim db = My.Settings.DB_Name
    11. Dts = New dsMain
    12. Dts.Persist(False, Dts.Tables.Cast(Of DataTable).Where(Function(tb) tb.PrimaryKey.Length = 0).ToArray) 'Tabellen ohne PrimKey-Column aus Persistierung rausnehmen
    13. Dts._sCon = $"Server={server}; UID={UID}; password={passwd}; Initial Catalog={db};"
    14. 'Dts._sCon = modZentraleAufgaben.GetConnectionString
    15. Dts._Persistance = New MySqlServerPersistance(Dts._sCon, Dts)
    16. [b]Dts._Persistance.Connection_EnterOpen()[/b]
    17. End Sub
    18. '......
    19. End Class



    In DbPersistanceBase.vb:

    VB.NET-Quellcode

    1. Imports System.Data.Common
    2. Imports System.Text.RegularExpressions
    3. Public MustInherit Class DbPersistanceBase
    4. Public _RankedTables As New List(Of DataTable)
    5. Private _Adapters As Dictionary(Of DataTable, DbDataAdapter)
    6. Private _Dts As DataSet
    7. Private _ForeignKeyStatui As List(Of Tuple(Of ForeignKeyConstraint, AcceptRejectRule))
    8. Protected MustOverride Function CreateAdapter(table As DataTable) As DbDataAdapter
    9. Public Sub New(dts As DataSet)
    10. _Dts = dts
    11. dts.ExtendedProperty(Of DbPersistanceBase)(Me)
    12. 'Store the AcceptRejectRule of all datasets ForeignKeyConstraints
    13. _ForeignKeyStatui = Aggregate rl In _Dts.Relations.Cast(Of DataRelation)
    14. Let fk = rl.ChildKeyConstraint Where fk IsNot Nothing
    15. Select Tuple.Create(fk, fk.AcceptRejectRule) Into ToList
    16. BuildRankedTables()
    17. End Sub
    18. Private Function GetAdapter(table As DataTable) As DbDataAdapter
    19. If _Adapters Is Nothing Then [b]_Adapters = _RankedTables.ToDictionary(Function(tb) tb, Function(tb) CreateAdapter(tb))[/b]
    20. Return _Adapters(table)
    21. End Function
    22. '............
    23. Public Function Connection_EnterOpen() As IDisposable
    24. [b]Return GetAdapter(_RankedTables(0)).SelectCommand.Connection.EnterOpen[/b]
    25. End Function
    26. End Class



    Beim Aufruf _Adapters = _RankedTables.ToDictionary(Function(tb) tb, Function(tb) CreateAdapter(tb)) tritt dieser Fehler auf:

    System.TypeInitializationException: "Der Typeninitialisierer für "xx.dsMain" hat eine Ausnahme verursacht."
    Innere Ausnahme:
    MissingMethodException: Methode nicht gefunden: "MySql.Data.MySqlClient.MySqlCommand MySql.Data.MySqlClient.MySqlCommand.Clone()".



    An der Datenbank und den Zugangsdaten liegt es nicht, das haben wir sicherheitshalber ausprobiert.

    Die Ideen sind gerade ausgegangen
    --------
    Lieber inkompetent als inkontinent
    Vielen Dank für den Link zu Deinem (dem ersten von drei?) Tutorial. Den zweiten und dritten Teil konnte ich nicht finden.
    Zumindest einen Teil davon hast Du auch irgendwo auf Deutsch gemacht. Der Polizist, der sich nach Feierabend die Haare stylt, kam mir bekannt vor.
    Zu großartigen neuen Erkenntnissen hat die Lektüre nicht geführt. Mein Datenmodell ist gar nicht so schlecht, glaube ich. Ich habe auch wochenlang darüber nachgedacht.

    Aber leider hilft mir das nicht beim aktuellen Problem (s. Post #44). Natürlich habe ich schon min. 100 Mal den Hinweis gelesen, erstmal DataSetOnly alles fertig zu programmieren, aber ich fände es extrem beruhigend, den "echten" Datenbankzugriff mal kurz funktionierend gesehen zu haben.
    --------
    Lieber inkompetent als inkontinent
    @tragl:
    Gefunden, danke!


    @ErfinderDesRades:
    Ich komme mit dem Finden des Fehlers (Post #44) nicht weiter. Tragl hat bei der Suche geholfen. Sein Code ist in diesem Bereich identisch mit meinem. Er hat es testweise mit den Zugangsdaten zu meinem Webserver ausprobiert. Bei ihm kommt keine Fehlermeldung. Irgendetwas muß bei mir anders sein, aber was? Der Code in der DbPersistanceBase kommt von Dir. Wenn es jemand weiß, dann bestimmt Du :)
    Es wäre super, wenn wir das Problem gelöst bekämen.


    --------
    Lieber inkompetent als inkontinent

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

    100Volt schrieb:

    Beim Aufruf _Adapters = _RankedTables.ToDictionary(Function(tb) tb, Function(tb) CreateAdapter(tb)) tritt dieser Fehler auf:
    Kann ja nur etwas in der Methode CreateAdapter() sein. Da kann man mal einen Haltepunkt setzen und hoffen, dasser da stoppt.
    Bei Initializer-Exceptions ist das mit dem Debugging manchmal bischen zickiger.
    Ansonsten wird tragl da besser durchblicken als ich. Weil die MySqlDbPersistance ist ja von ihm, und bei ihm läuft sie auch.
    Ich hingegen habe ühaupt kein MySql.
    Wenn ich die Funktion GetAdapter im Einzelschritt-Debugmodus (F8) durchgehe, dann tritt der Fehler, auf wenn das hier groß geschriebene TB markiert ist:

    VB.NET-Quellcode

    1. _Adapters = _RankedTables.ToDictionary(Function(tb) TB, Function(tb) CreateAdapter(tb))

    Im ersten Schritt wird das erste Function(tb) aufgerufen und das tb dahinter wird der Rückgabewert sein, der verwendet wird. Der Fehler tritt dann nicht erst beim Aufruf von CreateAdapter(tb)) (also Tragls Code aus MySqlServerPersistance) auf.

    Ich verstehe allerdings nicht so ganz genau was bzw. wie diese Funktion etwas macht:

    VB.NET-Quellcode

    1. Private Function GetAdapter(table As DataTable) As DbDataAdapter
    2. If _Adapters Is Nothing Then _Adapters = _RankedTables.ToDictionary(Function(tb) tb, Function(tb) CreateAdapter(tb))
    3. Return _Adapters(table)
    4. End Function

    Da wird table übergeben und zurückgegeben, aber nix mit table gemacht? Die Funktion .ToDictionary, die aufgerufen wird, verstehe ich überhaupt nicht mehr.
    --------
    Lieber inkompetent als inkontinent

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „100Volt“ ()

    ErfinderDesRades schrieb:

    Ansonsten wird tragl da besser durchblicken als ich.

    Leider nicht, ich hab ja prinzipiell nur deine SqlServerPersistance umgebaut zu MySqlServerPersistance inhaltlich bis auf den anderen
    Data-Provider ja quasi gleich. Es werden die gleichen commands genutzt etc. Ich kann mir nicht erklären, warum das bei 100Volt nicht funktioniert... :?:

    Hier noch ein Vergleich:

    SqlServerPersistance
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Data.SqlClient
    2. Imports System.Data.Common
    3. Public Class SqlServerPersistance : Inherits DbPersistanceBase
    4. Private _Connection As SqlConnection
    5. Public Sub New(connectionString As String, dts As DataSet)
    6. MyBase.New(dts)
    7. #If False Then
    8. "MultipleActiveResultSets=true;" im ConnectionString sicherstellen
    9. Das ermöglicht, eine ChildTable mit Children der ersten eingetroffenen ParentRow zu befüllen, auch wenn die ParentTable-Befüllung noch garnet abgeschlossen ist
    10. Nützich bei Parent->Child->Child - Views
    11. #End If
    12. Dim builder = New SqlConnectionStringBuilder(connectionString) With {.MultipleActiveResultSets = True}
    13. _Connection = New SqlConnection(builder.ConnectionString)
    14. End Sub
    15. Private Shared Sub TryInitAutoIncrement(tb As DataTable, insertCommand As SqlCommand)
    16. 'Bei AutoIncrement-Primkeys wird dem Insert-CommandText ein Select-Command angehängt, welches den Db-seitig generierten Pk rücktransportiert
    17. Dim pk = tb.PrimaryKey
    18. If pk.Length <> 1 OrElse Not pk(0).AutoIncrement Then Return
    19. insertCommand.CommandText &= String.Format("; SELECT [{0}] FROM [{1}] WHERE [{0}] = SCOPE_IDENTITY()", pk(0).ColumnName, tb.TableName)
    20. insertCommand.UpdatedRowSource = UpdateRowSource.Both
    21. End Sub
    22. Protected Overrides Function CreateAdapter(table As DataTable) As DbDataAdapter
    23. Dim adp = New SqlDataAdapter(String.Format("Select [{0}].* from [{0}]", table.TableName), _Connection)
    24. Using builder = New SqlCommandBuilder(adp) With {.ConflictOption = ConflictOption.OverwriteChanges}
    25. With adp
    26. .UpdateCommand = builder.GetUpdateCommand.Clone
    27. .InsertCommand = builder.GetInsertCommand.Clone
    28. TryInitAutoIncrement(table, .InsertCommand)
    29. .DeleteCommand = builder.GetDeleteCommand.Clone
    30. .TableMappings.Add(DbDataAdapter.DefaultSourceTableName, table.TableName)
    31. End With
    32. End Using
    33. Return adp
    34. End Function
    35. End Class


    MySqlServerPersistance
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports MySql.Data.MySqlClient
    2. Imports System.Data.Common
    3. Public Class MySqlServerPersistance : Inherits DbPersistanceBase
    4. Private _Connection As MySqlConnection
    5. Public Sub New(connectionString As String, dts As DataSet)
    6. MyBase.New(dts)
    7. Dim builder = New MySqlConnectionStringBuilder(connectionString) 'With {.MultipleActiveResultSets = True} 'TRAGL: wird von MySQL nicht unterstützt
    8. _Connection = New MySqlConnection(builder.ConnectionString)
    9. End Sub
    10. Private Shared Sub TryInitAutoIncrement(tb As DataTable, insertCommand As MySqlCommand)
    11. 'Bei AutoIncrement-Primkeys wird dem Insert-CommandText ein Select-Command angehängt, welches den Db-seitig generierten Pk rücktransportiert
    12. Dim pk = tb.PrimaryKey
    13. If pk.Length <> 1 OrElse Not pk(0).AutoIncrement Then Return
    14. insertCommand.CommandText &= String.Format("; SELECT `{0}` FROM `{1}` WHERE `{0}` = LAST_INSERT_ID()", pk(0).ColumnName, tb.TableName)
    15. insertCommand.UpdatedRowSource = UpdateRowSource.Both
    16. End Sub
    17. Protected Overrides Function CreateAdapter(table As DataTable) As DbDataAdapter
    18. Dim adp = New MySqlDataAdapter(String.Format("Select `{0}`.* from `{0}`", table.TableName), _Connection)
    19. Using builder = New MySqlCommandBuilder(adp) With {.ConflictOption = ConflictOption.OverwriteChanges}
    20. With adp
    21. .UpdateCommand = builder.GetUpdateCommand.Clone
    22. .InsertCommand = builder.GetInsertCommand.Clone
    23. TryInitAutoIncrement(table, .InsertCommand)
    24. .DeleteCommand = builder.GetDeleteCommand.Clone
    25. .TableMappings.Add(DbDataAdapter.DefaultSourceTableName, table.TableName)
    26. End With
    27. End Using
    28. Return adp
    29. End Function
    30. End Class
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:
    Ich hatte in meinem vorherigen Post (#50) noch nachträglich hinzugefügt:
    Der Fehler tritt dann nicht erst beim Aufruf von CreateAdapter(tb) (also Tragls Code aus MySqlServerPersistance) auf.
    Das hatte sich mit Tagls Post #51 überschnitten.

    Da die Einzelschritt-Markierung noch nicht im zweiten Teil, nach dem Komma (Function(tb) CreateAdapter(tb)) ist, hat das m.E. nichts mit der Klasse MySqlServerPersistance zu tun, zumindest nicht mit der Funktion CreateAdapter.


    ---------------------------- NACHTRAG ----------------------------

    Offensichtlich liegt es doch an dieser Funktion in MySqlServerPersistance:

    VB.NET-Quellcode

    1. Protected Overrides Function CreateAdapter(table As DataTable) As DbDataAdapter
    2. Dim adp = New MySqlDataAdapter(String.Format("Select `{0}`.* from `{0}`", table.TableName), _Connection)
    3. Using builder = New MySqlCommandBuilder(adp) With {.ConflictOption = ConflictOption.OverwriteChanges}
    4. With adp
    5. '.UpdateCommand = builder.GetUpdateCommand.Clone
    6. '.InsertCommand = builder.GetInsertCommand.Clone
    7. 'TryInitAutoIncrement(table, .InsertCommand)
    8. '.DeleteCommand = builder.GetDeleteCommand.Clone
    9. .TableMappings.Add(DbDataAdapter.DefaultSourceTableName, table.TableName)
    10. End With
    11. End Using
    12. Return adp
    13. End Function


    ..denn so, mit den auskommentierten Zeilen, gibt es keinen Fehler.

    ---------------------------- NACHTRAG 2 ----------------------------

    Ich habe .Clone durch .CloneX ersetzt (kommt aus dem Helpers-Projekt vom EdR, glaube ich):

    VB.NET-Quellcode

    1. Protected Overrides Function CreateAdapter(table As DataTable) As DbDataAdapter
    2. Dim adp = New MySqlDataAdapter(String.Format("Select `{0}`.* from `{0}`", table.TableName), _Connection)
    3. Using builder = New MySqlCommandBuilder(adp) With {.ConflictOption = ConflictOption.OverwriteChanges}
    4. With adp
    5. .UpdateCommand = builder.GetUpdateCommand.CloneX
    6. .InsertCommand = builder.GetInsertCommand.CloneX
    7. TryInitAutoIncrement(table, .InsertCommand)
    8. .DeleteCommand = builder.GetDeleteCommand.CloneX
    9. .TableMappings.Add(DbDataAdapter.DefaultSourceTableName, table.TableName)
    10. End With
    11. End Using
    12. Return adp
    13. End Function


    Nun funktioniert es. Zumindest das Anlegen eines Datensatzes in der Datenbank auf dem Webserver war erfolgreich.
    Ich teste dann mal weiter und berichte...

    ---------------------------- NACHTRAG 3 ----------------------------

    Was mich gerade etwas irritiert ist, wenn ich:

    VB.NET-Quellcode

    1. Dts.Register(Me, False)
    2. Dts.Fill


    aufrufe, bei Dts.Fill keine Argumente (Tabellen) angebe, wird hier an der mit HIER gekennzeichneten Stelle in der Klasse DatasetXmlAdapter eine XML-Datei geladen:

    VB.NET-Quellcode

    1. Public Function Attach(dts As DataSet) As DatasetAdapterBase
    2. Attach = Nothing
    3. If DatasetAdapterBase.Attachs.TryGetValue(dts, Attach) Then Exit Function
    4. Attach = New DatasetXmlAdapter(dts) 'HIER
    5. DatasetAdapterBase.Attachs.Add(dts, Attach)
    6. End Function


    Hier bei DataFile.Refresh() crasht es dann, wenn es die XML-Datei nicht gibt:

    VB.NET-Quellcode

    1. Protected Overrides Sub _Fill(tbls As Collections.Generic.IEnumerable(Of DataTable))
    2. If tbls.Any Then Throw New NotSupportedException( _
    3. "Bei DatasetOnly werden immer alle Tabellen befüllt - bestimmte Tabellen anzugeben ist sinnlos")
    4. DataFile.Refresh()
    5. If DataFile.Exists() Then
    6. Dim tblls = _DataSet.Tables
    7. For Each tb As DataTable In DataSet.Tables
    8. tb.Attach.EnableComplete(False, True)
    9. Next
    10. _DataSet.Clear()
    11. Synchronisize(FileAccess.Read)
    12. For Each tb As DataTable In DataSet.Tables
    13. tb.Attach.EnableComplete(True, True)
    14. AcceptChangesRowwise(tb.Rows)
    15. Next
    16. DataSet.EnforceConstraints = True 'tb.BeginLoadData setzt EnforceConstraints.False
    17. Else
    18. 'MessageBox.Show(String.Concat( _
    19. ' "Leider (noch) kein DatenFile vorhanden", Lf, _
    20. ' "Sie können aber trotzdem fortfahren, und eines anlegen."))
    21. End If
    22. End Sub


    Keine Ahnung, ob das ein Bug oder Feature ist. Ich finde es jedenfalls irritierend, da ich mit dem Laden aller Tabelleninhalte aus der mySQL-DB gerechnet habe.


    --------
    Lieber inkompetent als inkontinent

    Dieser Beitrag wurde bereits 9 mal editiert, zuletzt von „100Volt“ ()

    100Volt schrieb:

    aufrufe, bei Dts.Fill keine Argumente (Tabellen) angebe, wird hier an der mit HIER gekennzeichneten Stelle in der Klasse DatasetXmlAdapter eine XML-Datei geladen:


    nö: wenn du Die MySqlPersistance nutzt dann lädt er den kompletten Datenbankinhalt, andernfalls die angegebene XML.
    Das wäre der weitere Schritt, die Tabellen partiell zu laden - soweit waren wir ja noch nicht
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:
    Doch, ganz sicher. Das ist der Ablauf:

    In frmMain:

    VB.NET-Quellcode

    1. Dts.Register(Me, False)
    2. Dts.Fill() 'SPRUNG NACH....


    hierhin in FormX:

    VB.NET-Quellcode

    1. Public Sub Fill(dts As DataSet, ParamArray tables() As DataTable)
    2. 'Dim sw = Stopwatch.StartNew
    3. dts.Attach.Fill(tables) 'SPRUNG NACH...
    4. 'Dbg(sw.ElapsedMilliseconds)
    5. End Sub


    hierhin in FormX:

    VB.NET-Quellcode

    1. Public Function Attach(dts As DataSet) As DatasetAdapterBase
    2. Attach = Nothing
    3. If DatasetAdapterBase.Attachs.TryGetValue(dts, Attach) Then Exit Function
    4. Attach = New DatasetXmlAdapter(dts) 'SPRUNG NACH...
    5. DatasetAdapterBase.Attachs.Add(dts, Attach)
    6. End Function


    hierhin in DatasetXmlAdapter:

    VB.NET-Quellcode

    1. Public Sub New(_Dts As DataSet)
    2. DataSet = _Dts
    3. #If DEBUG Then
    4. 'DataFile = New FileInfo("..\..\Daten\").Combine(_Dts.GetType.Name & ".xml")
    5. #Else
    6. DataFile = New FileInfo(Application.LocalUserAppDataPath).Combine(_Dts.GetType.Name & ".xml")
    7. #End If
    8. End Sub


    hierhin in FormX:

    VB.NET-Quellcode

    1. Public Function Attach(dts As DataSet) As DatasetAdapterBase
    2. Attach = Nothing
    3. If DatasetAdapterBase.Attachs.TryGetValue(dts, Attach) Then Exit Function
    4. Attach = New DatasetXmlAdapter(dts) 'KOMMT HIER ZURÜCK
    5. DatasetAdapterBase.Attachs.Add(dts, Attach)
    6. End Function


    hierhin in FormX:

    VB.NET-Quellcode

    1. Public Sub Fill(dts As DataSet, ParamArray tables() As DataTable)
    2. 'Dim sw = Stopwatch.StartNew
    3. dts.Attach.Fill(tables) 'KOMMT HIER ZURÜCK
    4. 'Dbg(sw.ElapsedMilliseconds)
    5. End Sub


    hierhin in DatasetAdapterBase:

    VB.NET-Quellcode

    1. Public Sub Fill(tbls As Collections.Generic.IEnumerable(Of DataTable))
    2. '_DataSet.Clear()
    3. _Fill(tbls) 'SPRUNG NACH...
    4. End Sub


    hierhin in DatasetXmlAdapter:

    VB.NET-Quellcode

    1. Protected Overrides Sub _Fill(tbls As Collections.Generic.IEnumerable(Of DataTable))
    2. If tbls.Any Then Throw New NotSupportedException( _
    3. "Bei DatasetOnly werden immer alle Tabellen befüllt - bestimmte Tabellen anzugeben ist sinnlos")
    4. DataFile.Refresh() 'CRASH
    5. If DataFile.Exists() Then
    6. Dim tblls = _DataSet.Tables
    7. For Each tb As DataTable In DataSet.Tables
    8. tb.Attach.EnableComplete(False, True)
    9. Next
    10. _DataSet.Clear()
    11. Synchronisize(FileAccess.Read)
    12. For Each tb As DataTable In DataSet.Tables
    13. tb.Attach.EnableComplete(True, True)
    14. AcceptChangesRowwise(tb.Rows)
    15. Next
    16. DataSet.EnforceConstraints = True 'tb.BeginLoadData setzt EnforceConstraints.False
    17. Else
    18. 'MessageBox.Show(String.Concat( _
    19. ' "Leider (noch) kein DatenFile vorhanden", Lf, _
    20. ' "Sie können aber trotzdem fortfahren, und eines anlegen."))
    21. End If
    22. End Sub

    An der mit 'CRASH gekennzeichneten Stelle ist Ende.

    So Dts.Fill(Dts.tblKunden) kann ich mir die Tabellen einzeln laden, das funktioniert. Allerdings auch nur mit Tabellen, die einen Integer-Primarykey haben (zumindest geht String definitiv nicht).
    --------
    Lieber inkompetent als inkontinent
    @100Volt
    jo hatte mich vertan. Ich hab ne Methode geschrieben, die über Sql ALLE Tabellen aus der Datenbank befüllt. - such ich dir noch raus.
    Aber ist doch jetzt auch völlig irrelevant - wenn jetzt DB-Zugriff funzt dann bau erstmal alle deine Forms und Funktionen soweit fertig und teste
    das im XML. Alles Andere machen wir dann - sonst bist du immer an 2 Stellen zu Gange, und glaub mir: während dem Proggen änderst du vermutlich
    noch einiges an deinem DataSet.

    String-Relationen würde ich an deiner Stelle weglassen - das sorgt nur für Probleme, ich werd' meine Anwendung auch so umbauen dass ich der keine
    mehr hab.

    EDIT: hier - hab das in der DbPersistanceBase drin, du also folglich auch:

    VB.NET-Quellcode

    1. Public Sub FillAll()
    2. _Dts.Clear()
    3. Using Connection_EnterOpen()
    4. Dim enforced = _Dts.EnforceConstraints
    5. _RankedTables.ForEach(Sub(tb) tb.BeginLoadData())
    6. _RankedTables.ForEach(Sub(tb) GetAdapter(tb).Fill(tb))
    7. _RankedTables.ForEach(Sub(tb) tb.EndLoadData())
    8. _Dts.EnforceConstraints = enforced
    9. End Using
    10. End Sub


    damit lädst du sämtlichen Inhalt aus deiner DB in's DataSet

    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „tragl“ ()

    ok, aber wie rufe ich das auf? Mit Dts.FillAll jedenfalls nicht.


    Nun gibt es ein neues Problem. Ich kann nicht mehr auf mein DataSet zugreifen um mit meinem Code die Tabellen in der Datenbank zu erstellen. Der Aufruf von Dts.Register(Me, False) führt im weiteren Verlauf offenbar zur Kommunikation mit dem Datenbankserver, auf dem die Tabellen des DataSets dann nicht vorhanden sind.


    ------------------ NACHTRAG ------------------

    Da ich nur noch so dsMain.Dts auf mein DataSet zugreifen kann, dann aber der ganze DB-Helpers-Kram initialisiert wird, habe ich den Code auskommentiert, der die Probleme machte:

    VB.NET-Quellcode

    1. Protected Overrides Function CreateAdapter(table As DataTable) As DbDataAdapter
    2. Dim adp = New MySqlDataAdapter(String.Format("Select `{0}`.* from `{0}`", table.TableName), _Connection)
    3. Using builder = New MySqlCommandBuilder(adp) With {.ConflictOption = ConflictOption.OverwriteChanges}
    4. With adp
    5. '.UpdateCommand = builder.GetUpdateCommand.CloneX
    6. '.InsertCommand = builder.GetInsertCommand.CloneX
    7. 'TryInitAutoIncrement(table, .InsertCommand)
    8. '.DeleteCommand = builder.GetDeleteCommand.CloneX
    9. '.TableMappings.Add(DbDataAdapter.DefaultSourceTableName, table.TableName)
    10. End With
    11. End Using
    12. Return adp
    13. End Function



    Nun sind die Tabellen wieder angelegt. Wie ist denn der vorgesehene Weg zum Anlegen der Tabellen?

    --------
    Lieber inkompetent als inkontinent

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

    100Volt schrieb:

    Ich habe .Clone durch .CloneX ersetzt (kommt aus dem Helpers-Projekt vom EdR, glaube ich)
    Das deutet auf einen Strict-Off-Fehler hin - wäre zumindest eine Möglichkeit.
    Überprüfe mal, ob du in deinen Projekt-einstellungen Option Strict On eingestellt hast.
    Damit hätte der Compiler dir den Fehler sofort gesagt - hätteste nicht so lange suchen müssen.

    100Volt schrieb:

    Ich kann nicht mehr auf mein DataSet zugreifen um mit meinem Code die Tabellen in der Datenbank zu erstellen

    Jo du musst ja auch auf der frmMain das _DataSetXML = True setzen - dann kommuniziert der auch net mehr mit der DB. Dann kannste deine Tabellen da wieder anlegen lassen
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:
    @EdR:
    OptionStrict steht bei mir immer auf on. Habe ich gerade noch mal kontrolliert.


    @Tragl:
    ok, danke!


    Wenn ich mit Dts.Fill(Dts.tblAnrede) eine Tabelle laden möchte, biegt der Code immer irgendwo Richtung XML-Datei laden ab. Da es die nicht gibt, endet es im Fehler.

    Wie ist denn der vorgesehene Weg zum Laden vollständiger Tabellen? Komisch, daß ich als Einziger damit so große Probleme habe. Den Code nutzen doch bestimmt zig Leute.
    --------
    Lieber inkompetent als inkontinent

    100Volt schrieb:

    Wie ist denn der vorgesehene Weg zum Laden vollständiger Tabellen?

    Dts.TABELLE.CustomFill(BEDINGUNG) - hatten wir einige Posts vorher schon. Aber warum vertraust du nicht drauf und baust erstmal auf XML??? DIe Datenbank da später dranzuhängen ist ein Kinderspiel wenn dein
    DataSet vernünftig aufgebaut ist
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup: