.Net版SQLite無法訪問網路位置的資料庫檔案-winOpen,os_win.c 36702異常

來源:互聯網
上載者:User

標籤:

最近一個C#小程式,希望將SQLite資料庫放在網際網路共用的位置,讓多個用戶端同時訪問。卻發現SQLite串連不上該網路位置的資料庫,而如果資料庫在本地則一切正常。

例如將SQLite資料庫 test.dat 放在共用位置:\\System\Data\test.dat,
通過SQLite建立資料庫連接,執行Open時,將拋擲異常:

SQLite error (14): os_win.c:36702: (3) winOpen(D:\System\Data\test.dat) - 系統找不到指定的路徑。
SQLite error (14): os_win.c:36702: (3) winOpen(D:\System\Data\test.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:\Work\Program\WPF\MyMemory\MyMemory.Frame\DAL\SQLiteRunner.cs:行號 34
   在 MyMemory.Frame.DAL.DatabaseServices.CreateConnection() 位置 d:\Work\Program\WPF\MyMemory\MyMemory.Frame\DAL\DatabaseServices.cs:行號 23
   在 MyMemory.Frame.DAL.DatabaseServices.Initialize(String dataDir) 位置 d:\Work\Program\WPF\MyMemory\MyMemory.Frame\DAL\DatabaseServices.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.1\System.Data.SQLite\SQLiteConnection.cs Line 2372
SortedList<string, string> opts = ParseConnectionString(
          _connectionString, _parseViaFramework);

\sqlite-netFx-source-1.0.94.1\System.Data.SQLite\SQLiteConnection.cs Line 1875
arParts = SQLiteConvert.NewSplit(s, ‘;‘, true, ref error);

\sqlite-netFx-source-1.0.94.1\System.Data.SQLite\SQLiteConvert.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版:
下載

轉載請註明出處。

(全文完)


 

.Net版SQLite無法訪問網路位置的資料庫檔案-winOpen,os_win.c 36702異常

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.