zoukankan      html  css  js  c++  java
  • .Net版SQLite无法访问网络位置的数据库文件-winOpen,os_win.c 36702异常

    最近一个C#小程序,希望将SQLite数据库放在网络共享的位置,让多个客户端同时访问。却发现SQLite连接不上该网络位置的数据库,而如果数据库在本地则一切正常。

    例如将SQLite数据库 test.dat 放在共享位置:\SystemData est.dat
    通过SQLite创建数据库连接,执行Open时,将抛掷异常:

    SQLite error (14): os_win.c:36702: (3) winOpen(D:SystemData est.dat) - 系统找不到指定的路径。
    SQLite error (14): os_win.c:36702: (3) winOpen(D:SystemData est.dat) - 系统找不到指定的路径。
    SQLite error (14): cannot open file at line 36711 of [9491ba7d73]
    “System.Data.SQLite.SQLiteException”类型的第一次机会异常在 System.Data.SQLite.dll 中发生
    System.Data.SQLite.SQLiteException (0x80004005): unable to open database file
       在 System.Data.SQLite.SQLite3.Open(String strFilename, SQLiteConnectionFlags connectionFlags, SQLiteOpenFlagsEnum openFlags, Int32 maxPoolSize, Boolean usePool)
       在 System.Data.SQLite.SQLiteConnection.Open()
       在 MyMemory.Frame.DAL.SQLiteRunner..ctor(String connectionString) 位置 d:WorkProgramWPFMyMemoryMyMemory.FrameDALSQLiteRunner.cs:行号 34
       在 MyMemory.Frame.DAL.DatabaseServices.CreateConnection() 位置 d:WorkProgramWPFMyMemoryMyMemory.FrameDALDatabaseServices.cs:行号 23
       在 MyMemory.Frame.DAL.DatabaseServices.Initialize(String dataDir) 位置 d:WorkProgramWPFMyMemoryMyMemory.FrameDALDatabaseServices.cs:行号 54
    “System.Data.SQLite.SQLiteException”类型的第一次机会异常在 MyMemory.Frame.dll 中发生
    System.Data.SQLite.SQLiteException (0x80004005): unable to open database file
       在 System.Data.SQLite.SQLite3.Open(String strFilename, SQLiteConnectionFlags connectionFlags, SQLiteOpenFlagsEnum openFlags, Int32 maxPoolSize, Boolean usePool)
       在 System.Data.SQLite.SQLiteConnection.Open()
       ...

    即传入的SQLite网络共享路径(以\开头)在SQLite内部某个环节被转换成为了本地路径!

    问题处在SQLite提供的程序集内,那么SQLite最新版本是否已经修复这个问题了(或是从某版故意为之,不让访问网络共享位置的文件了呢)?
    到官网http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki下载最新版本( System.Data.SQLite 1.0.94.0 (3.8.6) )替换后重试,还是出现上面的异常。

    好吧,既然是开源的,那就下载源代码,看看是什么原因。

    下载了之后,采用VS编译,通过解决方案中自带的Test项目,可以输入数据库链接:

    点击Run就可以进入断点调试了。

    废话少说,直接上结果:

    Open过程问题点的方法调用过程如下

    sqlite-netFx-source-1.0.94.1System.Data.SQLiteSQLiteConnection.cs Line 2372
    SortedList<string, string> opts = ParseConnectionString(
              _connectionString, _parseViaFramework);

    sqlite-netFx-source-1.0.94.1System.Data.SQLiteSQLiteConnection.cs Line 1875
    arParts = SQLiteConvert.NewSplit(s, ';', true, ref error);

    sqlite-netFx-source-1.0.94.1System.Data.SQLiteSQLiteConvert.cs Line 716
    if ((character != EscapeChar) &&
                        (character != QuoteChar) &&
                        (character != separator))

    将上面的if ( //(character != EscapeChar) && 注释掉后半行(注意:不推荐这种注释代码的方法)
                        (character != QuoteChar) &&
                        (character != separator))

    再编译,重新执行Test.exe 一切OK。

    至于为什么有这个限制,源代码中的注释是:

                    // --Line 709
                    // HACK: Only consider the escape character to be an actual
                    //       "escape" if it is followed by a reserved character;
                    //       otherwise, emit the original escape character and
                    //       the current character in an effort to help preserve
                    //       the original string content.
                    // --Line 715

    官方文档说,放在网络位置共享访问的SQLite数据库,在某些特定情况下容易损坏。看来这个问题大神们解决不好,准备干脆屏蔽掉这种使用方式了。

    提醒一下,SQLite源码默认用的.Net Framework 4.5,编译时注意切换为项目需要的.Net Framework版本。

    最后提供修改后的System.Data.SQLite.dll .Net Framework 4.0版:
    下载

    转载请注明出处:原文http://www.cnblogs.com/yangzhj/p/4230123.html

    (全文完)

    -------------------------------------------
    2015-01-17 10:45 PS:

    发现之前提供的下载库x86版本编译有些问题。现已重新编译,且SQLite.Interop.dll均编译为静态链接,方便迁移使用。谢谢。


     

  • 相关阅读:
    wpf 命令
    wpf 事件
    wpf 依赖属性介绍
    wpf binging (六)多绑定
    ISI的晶圆级MRAM测试仪
    常见存储器分类
    存储器SDRAM简要历史
    当前MRAM市场以及专用MRAM设备测试的重要性
    IPUS SQPI PSRAM为STM32单片机提供RAM扩展方案
    单端口SRAM与双端口SRAM电路结构
  • 原文地址:https://www.cnblogs.com/yangzhj/p/4230123.html
Copyright © 2011-2022 走看看