WithCoderWithCoderWithCoder

C#.Net开发Sqlite时版本选择问题

    最近使用C#.NET开发SQLite数据库时,碰到一系列问题。专门从网上搜索了相关的资料,本文记录下来,以备后续参考。

    通常我们在开发一个C#.NET程序时,如果要自适应32位/64位系统,只需要在项目的“属性”->“生成”选项卡中,将“目标平台”设置为“Any CPU”。但是如果使用了SQLite,情况就不同了。

    首先,我们可以查看SQLite官网下载页面的说明:http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki

    SQLite的.NET开发包是System.Data.SQLite,兼容ADO.NET接口,也提供了Linq和Entity Framework 6实现。但这不重要,重要的是System.Data.SQLite是由两部分代码组成的,一部分是非托管的C++代码实现,一部分是托管代码与.NET框架接口。由于非托管代码是不能构建成“Any CPU”的,所以System.Data.SQLite的下载页面的每个包都是按32位或64位系统进行了区分的。

    我们查看SQLite的官网下载页面时,虽然在下载页面一开始就有大量的篇幅来说明如何选择下载,但看着System.Data.SQLite的下载页面就眼花缭乱,估计没有几个人能耐心看完。下面简单进行介绍:

    1. 首先是按类型分为安装包、非静态连接的二进制包和静态连接的二进制包。安装包会安装相关的动态库到系统内,并注册到GAC(Global Assembly Cache);两种二进制包的区别在于非托管部分的连接方式不同,非静态连接的二进制包在使用时需要VC运行时库的支持。需要注意的是:如果需要在Visual Studio中连接SQLite数据库,就必须选择合适的安装包进行安装。

    比如,要在Visual Studio 2010中连接SQLite,应该下载“qlite-netFx40-setup-bundle-x86-2010-1.0.113.0.exe”,这在下载包的说明中有明确黑体字说明。

    1-200Q210491X30.png

    安装之后就可以在Visual Studio 2010中连接SQLite了。

    2. 每个类型都按.NET版本分成了若干小组,目前从.NET 2.0 SP2到.NET 4.7.2,都有对应的支持版本。每个.NET版本又分为32位和64位两组。选用32位还是64位是根据使用系统来决定的。比如开发的时候是64位系统而发布后运行在32位系统上,就需要在开发时使用64位System.Data.SQLite.dll,而在发布时用32位的System.Data.SQLite.dll替换(这样使用比较麻烦,后面有相应的解决办法)。

    3. 在每个.NET版本分组中都有2个文件包,一个带有“bundle”字样,另一个没有。其中带有“bundle”字样的表示动态库是按混合模式编译的,在使用的时候只需要System.Data.SQLite.dll就可以了,而不带“bundle”的则是将非托管部分和托管部分分别编译,System.Data.SQLite.dll不能独立使用,还需要有SQLite.Interop.dll才能使用。

    编译使用Any CPU

    如果要使用“Any CPU”的System.Data.SQLite.dll,就必须使用不带“bundle”字样,即非混合编译的二进制包。

    非混合编译的二进制包有 System.Data.SQLite.dll 和 SQLite.Interop.dll 两个动态库。按官方说明,SQLite.Interop.dll可以放在与System.Data.SQLite.dll相同的目录下,也可以放在x86或x64子目录下,由System.Data.SQLite.dll 根据系统类型调用。为了确认,下载如下两个包(对应.net framework 4.5.1的32位和64位)来进行比较:

sqlite-netFx451-static-binary-Win32-2013-1.0.113.0.zip

sqlite-netFx451-static-binary-x64-2013-1.0.113.0.zip

    结果发现只有 SQLite.Interop.* 不同,其它文件都完全相同。

    1-200Q2113122419.png

    然后我们可以将两个包的 SQLite.Interop.* 分别放在x86和x64子目录下,合并成一个包。再在不同类型的系统下运行程序,可以看到结果都是完全通过。

    最后需要做的就是在Visual Studio项目中引用 System.Data.SQLite.dll,再将 x86\SQLite.Interop.dll 和 x64\SQLite.Interop.dll拷贝到项目根目录,包含在项目中,在属性中设置“如果较新则复制”或“始终复制”。编译后生成结果如下:

\bin\Debug
│  System.Data.SQLite.dll
│  Demo.exe
├─x64
│      SQLite.Interop.dll
└─x86
       SQLite.Interop.dll

    

欢迎分享交流,转载请注明出处:WithCoder » C#.Net开发Sqlite时版本选择问题