C# NHibernate ConnectionString mit Access DBs

Thaxll'ssillyia

Captain
Registriert
Dez. 2007
Beiträge
3.533
Hallo liebe Community,

ich häng gerade seit drei Stunden an einem Problem mit NHibernate und Access fest.

Mein Ziel ist einfach nur, (für mich erstmalig) eine Access-DB mit NHibernate anzusprechen. Dazu gibt es ja die schöne Spring-Konfig per xml:

HTML:
<?xml version="1.0"
  encoding="utf-8" ?>

<objects xmlns="http://www.springframework.net"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:db="http://www.springframework.net/database"
         xmlns:tx="http://www.springframework.net/tx"
         xsi:schemaLocation="http://www.springframework.net 
             http://www.springframework.net/xsd/spring-objects.xsd">

  <db:provider id="dbProvider"
               provider="Microsoft.Jet.OLEDB.4.0"
               connectionString="Data Source=Config\DB.mdb" />

  <object id="sessionFactory"
          type="Projekt.FluentSessionFactory, Projekt">
    <property name="DbProvider"
              ref="dbProvider" />
    <property name="HibernateProperties">
      <dictionary>
        <entry key="connection.provider"
               value="NHibernate.Connection.DriverConnectionProvider" />
        <entry key="dialect"
               value="NHibernate.JetDriver.JetDialect, NHibernate.JetDriver" />
        <entry key="connection.driver_class"
               value="NHibernate.JetDriver.JetDriver, NHibernate.JetDriver" />
        <entry key="show_sql"
               value="true" />
      </dictionary>
    </property>

    <property name="MappingAssemblies">
      <list>
        <value>Projekt</value>
      </list>
    </property>
  </object>

  <object id="transactionManager"
          type="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate32">
    <property name="DbProvider"
              ref="dbProvider" />
    <property name="SessionFactory"
              ref="sessionFactory" />
  </object>
  <tx:attribute-driven transaction-manager="transactionManager" />

</objects>

Mein Problem ist, dass ich immer die Fehlermeldung bekomme, dass der Provider unbekannt ist:

{"No object named 'Microsoft.Jet.OLEDB.4.0' is defined : Cannot find definition for object [Microsoft.Jet.OLEDB.4.0]"}

Im Netz war die erste Lösung, mein Projekt auf 32-bit umzuschalten, da es JET nicht für 64-bit gibt. Gesagt getan, bekomme trotzdem den Fehler.

Die nächste Empfehlung war, es nicht mit Jet zu probieren, sondern mit ACE (https://www.microsoft.com/en-us/download/confirmation.aspx?id=13255). Hab ich installiert, jetzt bekomme ich wieder den Provider-nicht-gefunden-Fehler:

{"No object named 'Microsoft.ACE.OLEDB.12.0' is defined : Cannot find definition for object [Microsoft.Jet.OLEDB.4.0]"}

Abgesehen davon muss es auch beim Kunden laufen, der hat zwar Office, allerdings bestimmt nicht die verlinkten Extra-Connectoren auf dem Rechner. Es bringt mir ja gar nix, wenn es nur auf meinem Rechner läuft...


Hat jemand eine Idee? Bin für jede Hilfe sehr dankbar!

Gute Nacht wünscht
Thax
 
Moin,

die Fehlermeldung lässt darauf schließen, dass er die Bibliothek nicht findet, also frag ich einfach mal zur Sicherheit nach. Hast du auch die "NHibernate.JetDriver.dll" in dein Projekt eingebunden?

Wie hast du NHibernate bezogen? Falls du es über nuget (siehe https://www.nuget.org/packages/NHibernate/) gemacht hast, dann gibt es den Treiber dort (siehe https://www.nuget.org/packages/NHibernate.JetDriver/).

Ansonsten brauchst du das NHibernateContrib Package (siehe https://developer.jboss.org/wiki/Da...nate?_sscc=t#jive_content_id_Microsoft_Access).

Noch ein Hinweis, der Treiber ist anscheinend nicht fehlerfrei (siehe letzter Link!):
There are still few problems with join syntax in queries that use more than one join. This driver passes 93% of NHibernate tests (there are 23 failing tests).
 
Zuletzt bearbeitet:
Jo, Nhibernate.Jet hab ich über Nuget drin, ebenso wie Nhibernate und den Spring Kram. Jeweils letzte Version.
 
Hast du mal geprüft ob die DLL im Output Directory liegt? Ist Copy Local auf "True" gestellt. Zur Sicherheit auch noch Private auf "True" stellen, sonst kann es passieren, dass wenn bei dir was im GAC ist, dass er Sie nicht ins Output kopiert. Wenn es das nicht ist dann wird es für mich auf Anhieb so erstmal schwierig.

Aber ich bin natürlich ein neugierier Mensch und weil ich selbst seit 7 Jahren hauptberuflich .NET Programmierer bin und schon sehr viel mit NHibernate umgesetzt habe, werde ich das ganze morgen mal fix auf Arbeit mit einem Projekt ausprobieren. MS Access hatte ich bis jetzt noch nicht angebunden. Wir verwenden allerdings kein Spring sondern StructureMap. Nicht das hier der Hund begraben liegt. Aber es sieht fast nicht danach aus, da NHibernate ja schon versucht, den Provider zu initialisieren. Bei mir ist die Datenbankverbindung nämlich immer bei den HibernateProperties weiter unten dabei. So ist es auch auf dem letzten Link beschrieben. Von dem bisschen Kontakt den ich mit Spring hatte, fällt mir auf Anhieb aber nichts auf :(

Ich melde mich morgen wieder.
 
Zuletzt bearbeitet:
Danke für deine Mühe. Die Dll steht auch auf CopyLocal = true.

Meine verwendeten Versionen von Bibliotheken über Nuget:

Common.Logging & Common.Logging.Core 3.3.1
Spring.Data & Spring.Aop & Spring.Core 2.0.1
Spring.Data.NHibernate4 2.0.1
NHibernate 4.0.4.4000
NHibernate.JetDriver 2.0.0.1002
Iesi.Collections 4.0.1.4000
FluentNHibernate 2.0.3

.NEt Framework ist 4.6.1 bei 32-bit. Ist ne WPF-Anwendung mit zugehörigem Testprojekt.
 
Moin,

also jetzt wird es verzwickt, denn bei mir läuft es auf Anhieb in meinem Projekt, dass vorher gegen eine Oracle DB lief. Habe nur den JetDriver eingebunden, eine Access MDB Datei mit einer Tabelle erstellt, alle Mapping Definition für die Oracle DB rausgeschmissen, eine Mapping Definition für die Tabelle in der Acess Datei erstellt und ich kann problemlos Daten lesen und schreiben.

Die Bibliotheken über nuget in unserem Projekt sind folgende:

CommonServiceLocator 1.3
Iesi.Collections 4.0.1.4000
log4net 2.0.3
NHibernate 4.0.4.4000
NHibernate.JetDriver 2.0.0.1002
Oracle.ManagedDataAccess 12.1.022
Prism 5.0.0
Prism.Composition 5.0.0
Prism.Interactivity 5.0.0
Prism.MEFExtensions 5.0.0
Prism.Mvvm 1.1.1
Prism.PubSubEvents 1.1.2
structuremap 3.1.6.186
WpfLocalizeExtension 2.3.2
XAMLMarkupExtensions 1.2.1.3

Das .NET Framework 4.5 ist im Projekt eingestellt und wir erstellen eine 32-Bit Anwendung. Es handelt sich ebenfalls um eine WPF-Anwendung. Wie hast du denn das Erstellen der 32-Bit Anwendung konfiguriert? Wir haben das über den Configuration Manager der Solution für alle Projekte gemacht.

Der Unterschied liegt jetzt in der Framework Version und im Spring Framework und der damit zusammenhängenden Konfiguration des ConnectionStrings.

Ich hab dir mal drei Bilder für den Configuration Manager, meine NHibernate Konfiguration und die Projekteinstellungen der Referenzen angehängt.

Ach und was mir noch einfällt, läuft es nur beim Kunden nicht oder auch lokal bei dir? Ich hab das natürlich jetzt nur auf meinem Entwickler Rechner getestet. Bei mir ist im übrigen Office 2010 installiert, falls das noch irgendwie eine Rolle spielt.

2016-01-26 07_23_00-Configuration Manager.png 2016-01-26 07_23_34-Krones.AnalysisTools.Complete - Microsoft Visual Studio.png 2016-01-26 07_30_20-Krones.AnalysisTools.Complete - Microsoft Visual Studio.png
 
Zuletzt bearbeitet:
Danke für die Info. Kannst du bitte mal deine komplette Lib-Liste zeigen, die in deinem Projekt referenziert wird? Vielleicht fehlt mir ja eine Standard-Lib.

32-bit hab ich ebenfalls über den Configuration Manager konfiguriert.

Beim Kunden war das noch nie, ist eine Software, die noch in der Erstentwicklung ist. Bei mir ist Office 2013 installiert.
 
Aber gerne doch! Im Startprojekt sieht das so aus (ich habe die Referenzen auf die eigenen Projekte weggelassen):

2016-01-27 12_53_07-Krones.AnalysisTools.Complete - Microsoft Visual Studio.png 2016-01-27 12_53_17-Krones.AnalysisTools.Complete - Microsoft Visual Studio.png

Edit: Ach die NHibernate.JetDriver fehlt, da ich die Änderungen schon reverted habe. Das war aber die Einzige DLL die noch eingebunden war.
 
Zuletzt bearbeitet:
So, Hollowman hat jetzt die Lösung gefunden, der Fehler lag in der falschen Verwendung des Providers. Dazu die richtige Spring.Database.xml:
HTML:
<?xml version="1.0"
  encoding="utf-8" ?>

<objects xmlns="http://www.springframework.net"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:db="http://www.springframework.net/database"
         xmlns:tx="http://www.springframework.net/tx"
         xsi:schemaLocation="http://www.springframework.net 
             http://www.springframework.net/xsd/spring-objects.xsd">

  <object id="sessionFactory"
          type="<Projekt>.Model.Mapping.FluentSessionFactory, <Projekt>">
    <property name="HibernateProperties">
      <dictionary>
        <entry key="connection.provider"
               value="NHibernate.Connection.DriverConnectionProvider" />
        <entry key="dialect"
               value="NHibernate.JetDriver.JetDialect, NHibernate.JetDriver" />
        <entry key="connection.driver_class"
               value="NHibernate.JetDriver.JetDriver, NHibernate.JetDriver" />
        <entry key="connection.connection_string"
               value="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Config\Database.mdb"/>
        <entry key="show_sql"
               value="true" />
      </dictionary>
    </property>

    <property name="MappingAssemblies">
      <list>
        <value><Projekt></value>
      </list>
    </property>
  </object>

  <object id="transactionManager"
          type="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate4">
    <property name="SessionFactory"
              ref="sessionFactory" />
  </object>
  <tx:attribute-driven transaction-manager="transactionManager" />

</objects>

Auch hatte ich im TransactionManager die falsche Assembly angegeben (Nhibernate4 ist richtig).

Vielen Dank an Hollowman!

Gruß Thax
 
Ich möchte noch ergänzen, dass diese Code Zeile auf die in Spring.NET hinterlegten Provider zurückgreift und dort der JetDriver natürlich nicht bekannt ist. Spring.NET hat jedoch generell keinen eigenen MS Access Provider. Mit der Lösung im Post davor greift er auf die NHibernate Provider zurück. Ich persönlich bin der Meinung, dass diese auch generell zu bevorzugen sind.

Code:
...
xmlns:db="http://www.springframework.net/database"
...
<db:provider id="dbProvider" provider="Microsoft.Jet.OLEDB.4.0" connectionString="Data Source=Config\DB.mdb" />
...
 
Zurück
Oben