Well this week i started work on my new development machine – a 64bit Windows 7 machine mmmm tasty. Everything has run perfectly smoothly until i hit one weird little issue. While attempting to generate a new data layer for a SQLite database using Subsonic i received nothing but errors – Another simple fix which I'll show you in this post.
Another day, another drama
So there i was happily coding away, loving my oober quick build times and that overall new machine feel when i hit upon this snag. Subsonic’s sonic.exe was building my DAL perfectly on all my SQL databases but i have one lightweight service that uses a SQLite database for its persistence. Subsonic is awesome because of the fact that it supports quite a few database types and SQLite is one of them.
Subsonic does this by using the fantastic System.Data.SQLite library that can be found @ http://sqlite.phxsoftware.com/ – more specifically it uses the 32bit version 1.0.60 of the library. Now as anyone who builds for both 64bit and 32bit will tell you with .Net libraries, if you don’t specify a single platform, by default Visual Studio will build for both. This works great in most instances, however if your library contains a reference to a library that is built specifically for only one and your library loads in a different platform to the one required by the reference, an exception will be thrown.
ERROR: Trying to execute generate Error Message: System.BadImageFormatException: Could not load file or assembly 'System.Data.SQLite, Version=18.104.22.168, Culture=neutral, PublicKeyToken=db937bc2d44ff139' or one of its dependencies. An attempt was made to load a program with an incorrect format. File name: 'System.Data.SQLite, Version=22.214.171.124, Culture=neutral, PublicKeyToken=db937bc2d44ff139' at SubSonic.SQLiteDataProvider.GetTableNameList() at SubSonic.SubCommander.Program.GenerateTables() in D:\@SubSonic\SubSonic\SubCommander\Program.cs:line 902 at SubSonic.SubCommander.Program.GenerateAll() in D:\@SubSonic\SubSonic\SubCommander\Program.cs:line 789 at SubSonic.SubCommander.Program.Main(String args) in D:\@SubSonic\SubSonic\SubCommander\Program.cs:line 90 WRN: Assembly binding logging is turned OFF. To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1. Note: There is some performance penalty associated with assembly bind failure logging. To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].
How can we fix it?
Well the issue in this instance is the fact that the System.Data.SQlite version that is packaged with Subsonic is a 32bit version. This makes the fix a simple one: simply replace the version in your sonic.exe folder with a 64bit one.
Your first step should be to go and download a copy of the 1.0.60 build of the System.Data.SQLite library.
At the time of writing it can be found here and you want to get the SQLite-126.96.36.199-binaries.zip:
The System.Data.SQLite library used by subsonic is stored in the same folder as the sonic.exe, if you originally used the Subsonic 2.1 Installer this will but the library in one of the following locations (if not it will be in the folder you put it in):
C:\Program Files (x86)\Subsonic\SubCommander\
All you need to do is replace the file System.Data.SQLite.dll with the one from the 64bit version of the build folder in the zip you downloaded.
Run Sonic.exe however you like (i use the visual studio extra’s way as outlined here) and your done!