Configuring FluentNHibernate with SQLite can be a bit painful, particularly because the SQLite assemblies are built separately for x86 and x64. On top of that, because NHibernate is loading the SQLite DLL at runtime, the DLL needs to be in a location that NHibernate can find it. When trying to set this up myself, I ran into the following error:
An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more details.
And the inner exception looked like this:
Could not create the driver from NHibernate.Driver.SQLite20Driver, NHibernate, Version=3.3.1.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4.
The Problem
Typically this error just means NHibernate cannot locate and load the SQLite DLL. This could be because you’re trying to load the 64-bit DLL under a 32-bit project or vice-versa. I noticed a lot of people were simply configuring their Visual Studio projects for x86 and referencing only the x86 SQLite DLL to solve this problem, but this is unnecessary. Below I’ll explain how to set this up properly.
The Solution
Basically the System.Data.SQLite DLL needs to be in the same directory as the NHibernate DLL. Typically, whichever Visual Studio project is set as the startup project (your main application interface) should have a reference to System.Data.SQLite. So just add the NuGet package to that project, as well as any test projects that may need access to the database as well.
The Long-winded Solution
Or if the above wasn’t clear enough…
Install FluentNHibernate
Firstly, you need to have FluentNHibernate installed and referenced in your project. For this, I would recommend installing NuGet.
After NuGet is installed, just grab the package using the GUI or run the Install-Package command from the NuGet prompt:
PM> Install-Package FluentNHibernate
You’ll reference FluentNHibernate from any project that uses it in the code, just like normal.
Configure FluentNHibernate
Make sure you’re building a valid NHibernate configuration in your code using Fluently.Configure() and that you’re using FluentNHibernate.Cfg.Db.SQLiteConfiguration.
Install SQLite
Using NuGet, grab the package using the GUI or run the Install-Package command from the NuGet prompt:
PM> Install-Package System.Data.SQLite
Make sure you’re installing System.Data.SQLite and NOT installing System.Data.SQLite.x86 or System.Data.SQLite.x64. The System.Data.SQLite package contains both the x86 and x64 versions of the DLL, which is what I would recommend if you want to compile your application for both 32-bit and 64-bit machines.
Reference SQLite
Add to reference to System.Data.SQLite to your primary application project (e.g. the startup project, the GUI, etc.). Also add a reference to any test projects that use the database, such as your NUnit tests.
You’re Done?
Does it work? If so, congrats! Happy coding!
It Didn’t Work
Ok, so if it didn’t work, you can try telling .NET which assembly to load.
Update Your App.config or Web.config
In your App.config or Web.config for your main application or any other projects that access the database, add the following:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<qualifyAssembly partialName="System.Data.SQLite"
fullName="System.Data.SQLite, Version=1.0.84.0,
Culture=neutral, PublicKeyToken=db937bc2d44ff139"/>
</assemblyBinding>
</runtime>
The qualifyAssembly element specifies the full name of the assembly that should be dynamically loaded when a partial name is used; this should ensure the correct version is loaded at runtime.
Also, if you’re wondering how I got the PublicKeyToken for the DLL, check out my article on finding the public key token for a .NET DLL or assembly.
Finish Line
You’re all done! Now you can use FluentNHibernate and SQLite in both x86 and x64 mode. The correct DLL should be loaded based on your project/compiler settings.
Happy hacking!