DBExtensions: Fehler bei Initialaisierung einer Access-Datenbank

  • VB.NET

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von us4711.

    DBExtensions: Fehler bei Initialaisierung einer Access-Datenbank

    Hallo Forum,

    bisher habe ich die DBExtensionbs des Erfinder des Rades mit Erfolg benutzt.
    Nunmehr versuche ich, auch bei einer Access-Datenbank diese grandiosen Tools einzusetzen und laufe dabei in ein Problem bei folgendem Initialisierungscode:

    VB.NET-Quellcode

    1. Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    2. Me.MitgliederDataSet.PersistAll()
    3. Dim adp = New DatasetAdapter(OleDbFactory.Instance, My.Settings.MitgliederConnectionString, ConflictOption.OverwriteChanges)
    4. Me.MitgliederDataSet.Adapter(adp).Register(Me)
    5. AddHandler Me.FormClosing, Me.MitgliederDataSet.HandleFormClosing
    6. MitgliederDataSet.Fill()
    7. End sub

    Bei erreichen der Zeile

    VB.NET-Quellcode

    1. Me.MitgliederDataSet.Adapter(adp).Register(Me)
    verabschiedet sich das Programm kommentarlos.
    Singlestep in die EDR-Extensions führt in den Bereich DatasetX und dort zu folgender Funktion:

    VB.NET-Quellcode

    1. ''' <summary>
    2. ''' sets the manager of all Tables, TableAdapters and BindingSources and stuff
    3. ''' </summary>
    4. <Extension()> _
    5. Public Function Adapter(ByVal dts As DataSet, ByVal value As DatasetAdapter) As DataSet
    6. Dim adp = dts.Adapter
    7. If adp.NotNull Then
    8. If adp Is value Then Return dts
    9. Throw value.Exception("Dataset.Adapter already initialized")
    10. End If
    11. value.DataSet = dts
    12. DatasetAdapterBase.Attachs(dts) = value
    13. Return dts
    14. End Function

    Beim Erreichen der Zeile

    VB.NET-Quellcode

    1. value.DataSet = dts
    bricht das Programm kommentarlos ab. Parameter dts .

    Was könnte der Grund für diese Verhalten sein?
    Ich habe zwischenzeitlich überlegt und ausprobiert:

    Gearbeitet wird mit VS 2012 professional
    Die EDR-Extensions sind compiliert als Release/AnyCPU
    Der oben gezeigte Code in Form_Load funktioniert einwandfrei unter Win7+Win8 als x86-Application.
    Projekt ist am Wochenende auf eine x64-Maschine umgezogen, und da ist dann der Fehler aufgetaucht.

    In der EDR-Solution AllTogether2010 habe ich dann Northwind aktiviert, mit dem gleichen Ergebnis an gleicher Stelle.
    Scheint also irgendwas mit x86/x64 zu tun zu haben.

    Das Projekt war von Haus aus auf Plattform: Ziel-CPU: AnyCPU und ebenso Erstellen: AnyCPU eingestellt. Nachdem ich hier jeweils x86 eingestellt habe, brach das Programm nicht mehr ohne Fehlermedung ab, sondern der Code nach

    VB.NET-Quellcode

    1. Me.MitgliederDataSet.Adapter(adp).Register(Me)
    wurde wohl einfach übersprungen. Die Form wurde richtig angezeigt, aber ohne Daten.

    Weiteres 'rumprobieren ergab dann funktionierenden Code (Try and Error) dadurch, das die Zeile

    VB.NET-Quellcode

    1. Me.MitgliederDataSet.PersistAll()
    auskommentiert wurde. Auch persistieren mit

    VB.NET-Quellcode

    1. Me.MitgliederDataSet.Save(Me)
    funktioniert einwandfrei.

    Offensichtlich bereitet der Umzug von x86 auf x64 erhebliche Probleme:

    Das Ganze ohne die EDR-Extensions klassisch mit Tableadapter funktionierte bei den Projekteinstellungen ausschliesslich mit x86, bei x64 und AnyCpu schmierte der Startvorgang (ebenfalls ohne Fehlermeldung) genauso ab bei Adapter.Fill im Dataset-Code.

    Verstehe ich hier was grundsätzlich nicht, oder gibt es da doch ein Problem mit dem OleDB-Treiber?
    Ist glaub immer problematisch, Dlls einzubinden, die mit vom Hauptprogramm abweichenden KompilierOptionen kompiliert sind.
    Ich bin auch immer zu doof mir zu merken, was AnyCpu, X86, X64 eiglich bedeuten, ich glaub eine Crux ist, dasses unterschiedliche Prozessor-Bitbreiten sind (32/64) sind, oder?

    Komisch nur, dasses bei dir ühaupt kompiliert, bei mir gibts da immer 102 Fehler.
    Aber ich hab ja auch immer die Dlls als Sources eingebunden.
    @Erfinder des Rades
    Ich habe Deine Extensions (DBExtensions, GeneralHelpers und WinFormHelpers) als AnyCPU sowohl für Plattform, als auch für Ziel-CPU kompiliert (Empfehlung der Fa. KleinstWeich) und per DDL-Verweis in meine Projekte eingebunden. Funzt einwandfrei, gute Arbeit :thumbsup: .
    Soweit getestet, funktionieren alle Funktionen sowohl unter x86 (32-Bit Maschinen) als auch unter x64 (64-Bit Maschinen). Das gilt auch für die Datenbank-Erweiterungen für Dataset-Only, MySql, SQLServer/-Express, und eigentlich auch für OleDB (MS-Access).
    Lediglich der Aufruf dieser einen Funktion (Dataset.PersistAll) führt anschliessend bei der Zuordnung des DatasetAdapters zu den in Post #4 genannten Problemen.
    Wenn ich mir den Code hinter Dataset.PerisistAll anschaue, ist eigentlich nichts weltbewegendes zu erkennen, Exceptions werden dort auch nicht ausgelöst.
    Hast Du 'nen Ansatz, was da los sein könnte?

    Bei Verzicht auf Dataset.PerisistAll läuft IMo und soweit erkennbar alles einwandfrei, aber es bleibt naturlich ein unsicheres Gefühl ...
    ich kanns nicht testen, weil ich hab halt nur eine 32bit-Mühle.

    Also ich kriege einen Fehler, wenn ich .PersistAll aufrufe für ein Dataset, was Tabellen enthält, die keine 1:1 - Entsprechung inne DB haben - die also nicht persistierbar sind.
    Das Northwind-Dataset ist so ein Dataset, also da ist logisch, bei .PersistAll einen Fehler zu kriegen, denn die CheckedCategory-Tabelle ist nur im Dataset angelegt, nicht inne DB.
    Aber da kriege ich eine vernünftige Meldung.

    hast du mal einen TryCatch drum gemacht, und ex.Tostring ausgegeben?

    us4711 schrieb:

    aber es bleibt naturlich ein unsicheres Gefühl ...
    Ich arbeite auch erfolgreich mit den DBExtensions von EDR - aber mit VS2010.
    Den Befehl PersistsAll habe ich bis jetzt noch nie angewendet und ich glaube auch ohne ihn noch keine Nachteile gehabt zu haben...

    Vor Kurzem habe ich mir einen neuen PC mit Win x64 zulegen müssen, da musste ich wegen der Meldung
    'Der Microsoft.ACE.OLEDB.12.0-Provider ist nicht auf dem lokalen Computer registriert'
    bei der ZielCPU x86 einstellen ... jetzt geht's aber nach vielen Herumprobieren auf einmal auch mit AnyCPU :?:

    Der obige Befehl unter x86 erzeugt bei mir keinen Fehler oder Absturz...

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

    jo, PersistAll() ist nur eine strenge Überprüfung, ob auch alle Tabellen persistierbar sind, falls nicht - dann Fehler.
    Ohne PersistAll() gibts keinen Fehler, sondern er deaktiviert einfach die Lade/Speicher-Funktion.
    Auf diese Weise kann man temporäre Tabellen im Dataset haben, die nicht persistieren.

    Sauberer hingegen ist, man gibt an, welche Tabellen temporär sind (Dataset.Persist(false, paramArray() datatable), bzw. .PersistAll(), wenn alle Tabellen persistieren sollen.
    Ich möchte, obwohl's jetzt ohne PeristAll funktioniert, doch versuchen, der Ursache auf den Grund zu gehen.
    ImMom baue ich 2 virtuele Maschinen mit Win7, einmal x86 und x64. installiere VS2012, erstelle ein triviales Projekt mit EDR-Extensions und einfacher Access-Mdb ohne Spielereien und teste mal mit die Ergebnisse:
    Einmal mit PersistALL und einmal klassisch über Tableadapter, mitx86, x64 und AnyCpu

    Ich denke, am Wochenende kann ich berichten, bin selbst auf die Ergebnisse gespannt.
    UPDATE:

    Also, ich habe nun wie oben beschrieben, Testumgebungen in x86 und x64 aufgebaut, und das oben beschriebene Verhalten hat sich auch hier bewahrheitet.
    Unter x32 laufen die EDR-Beispiele vollständig einwandfrei. Lediglich der Import System.Data.SqlServerCe wird angemeckert: Falsche Version. Dem bin ich aber noch nicht nachgegengen, hat z.Zt. aber auch keine Priorität.
    Nur unter x64 zickt das System wie oben beschrieben. Eigentümlich ist auch, das unter x64 keine Fehlermeldungen geworfen werden.
    Weitere Recherche dazu hat nun ergeben, das dies offenichtlich auch ein hier im Forum bekanntes Phänomen ist (IDE behandelt Exceptions nicht mehr, und dies auch bei Fa. KleinstWeich durchaus seit zumindest 2003 bekannt ist (The case of the disappearing OnLoad exception – user-mode callback exceptions in x64).
    Es gibt da wohl einen System-Patch als Hotfix (Ausnahmen, die von einer Anwendung ausgelöst werden, die in eine 64-Bit-Version von Windows ausgeführt wird, werden ignoriert), der jedoch bei mir ohne Wirkung blieb.

    Der einzige Ausweg zum Ergalt von Exceptions innerhalb eines FormLoad-Events unter x64 scheint also wirklich zu sein, den exceptionverdächtigen Code eben NICHT in der FormLoad-Routine unterzubringen.

    Das ist dann Arbeit für das weitere Wochenende, ich werde dann berichten, natürlich auch über das Dataset.PersistAll unter x64.

    Da fällt mir gerade ein: Zu prüfen wäre auch, ob das beschriebene Verhalten nur im Debugger, oder auch in den zugehörigen Exe-Dateien (Debug und Release) auftritt.
    Hat etwas gedauert, aber ich bin zu folgenden Ergebnissen gelangt:

    Die Resultate habe ich anhand des beigefügten Beispielprojektes ermittelt.

    Vorab: @ErfinderDesRades ist vollkommen unschuldig :P . Die aufgetretenen Probleme treten ausschliesslich auf einem 64-Bit System auf. Tatsächlich hat @vb1963 den richtigen Hinweis gegeben.

    Ergebnisse zusammengefasst, Detils in den Kommentaren des Beispielprojektes:

    • Erwartbares Verhalten auf 32-Bit Systemen, Exceptions werden überall ausgelöst.
    • Anderes Verhalten auf 64-Bit Systemen:
      [-] Kein Auslösen von Exceptions in Form_Load-Events (Google sagt: It's not a bug, it's a feature ...)
      [-] Normales Auslösen von Exceptions in Form_Shown
      und
      [-] Normales Auslösen von Exceptions bei Wertzuweisung von Instanzvariablen, e.g: Dim TestInt as Int32=Cint("Hallo")

      Fazit: Meide in 64-Bit Systemen Initialisierungen im Form_Load Event.

      Nicht getestet habe ich in x64-System Initialisierungen innerhalb einer Sub Main . Hat da vielleicht jemand schon Erfahrungen?


    Dateien