2010-11-23 102 views
27

我在C#中使用SQLite,並且有一些外鍵已定義的表。在SQLite中啓用外鍵約束

現在,我知道默認情況下,外鍵約束不會在SQLite中強制執行,但我想打開它們。

是否有可能通過代碼來做到這一點?我查了一下相關的question,但我不知道如何通過C#代碼來完成。我正在使用可用於Visual Studio 2008的SQLite的最新插件來設計我的表格。

conn.Open(); 
SQLiteCommand cmd = new SQLiteCommand("PRAGMA foreign_keys = ON", conn); 
cmd.ExecuteNonQuery(); 
conn.Close(); 

當需要重新打開此連接時,我需要此更改才能保留。可能嗎?

回答

47

最後從this post想通了這一點。 PRAGMA foreign_key設置不​​會持續,但您可以在每次在ConnectionString中建立連接時設置它。這使您可以使用Visual Studio的表格適配器。

  1. 請確保您安裝了system.data.sqlite的latest version(1.0.73.0)(1.0.66.0不起作用)。
  2. 更改您的ConnectionStringdata source=C:\Dbs\myDb.db;foreign keys=true;(用您的sqlite數據庫替換C:\ Dbs \ myDb.db)。
4

接通編譯:

PRAGMA foreign_keys = ON; 

您可以像任何其他SQL語句執行此。

+1

我正在使用SqliteDataAdapter,它管理連接的打開和關閉。我相信當連接關閉時,這些信息就會丟失。我怎樣才能讓這些信息持續存在? – kaustubh 2010-11-23 09:26:17

+0

@kaustubh:你說得對,foreign_key編譯指示是會話本地的。我不知道SqliteDataAdapter是如何工作的,但它似乎在其構造函數中使用了SQLConnection參數。您可以在創建連接時發佈該連接的編譯指示嗎? – 2010-11-23 09:35:41

+0

似乎沒有辦法在連接字符串中指定此信息。有什麼方法可以指定每次打開連接時執行的命令? – kaustubh 2010-11-23 09:49:29

1

看起來像你可以在數據庫連接上執行SQL命令PRAGMA foreign_keys = ON;就像選擇或更新語句一樣。儘管你必須確保你的SQLite是用外鍵等編譯的。見Here

2

這些應該提供你正在尋找的信息:

http://www.sqlite.org/faq.html#q22

http://www.sqlite.org/foreignkeys.html#fk_enable

總之,3.6.19版之前的版本不強制外鍵可言,但他們可使用觸發器進行模擬;從3.6.19開始,外鍵可以強制執行,但這需要使用PRAGMA foreign_keys = ON語句在每個連接上啓用,並且sqlite必須在啓用觸發和外鍵支持的情況下進行編譯(我認爲這對於任何二進制分配)。

1

添加到您的連接字符串:";EnforceFKConstraints=Yes|True|1;"

2

另一種解決方案是對每個查詢執行「PRAGMA foreign_keys = ON」。

 
    SQLiteConnection connection = new SQLiteConnection("Data Source=" + dbSQLite + ";Read Only=False;"); 
    connection.Open(); 
    SQLiteCommand mycommand = new SQLiteCommand(connection); 
    mycommand.CommandText = "PRAGMA foreign_keys=ON"; 
    mycommand.ExecuteNonQuery(); 
    mycommand.CommandText = "DELETE FROM table WHERE ID=x"; 
    mycommand.ExecuteReader(); 
    connection.Close(); 

如果你把它放在你傳遞CommandText的函數中,你可以重用它。

3

我也很難處理這個問題。我決定調查在連接到數據庫時在SQLDriverConnect()中生成的完整連接字符串。這是它返回的內容:

'Driver={SQLite3 ODBC Driver};Database=C:\Users\Staples\Documents\SQLLiteTest.s3db;StepAPI=;SyncPragma=;NoTXN=;Timeout=;ShortNames=;LongNames=;NoCreat=;NoWCHAR=;FKSupport=;JournalMode=;OEMCP=;LoadExt=;BigInt=;PWD=' 

正如你所看到的那樣,有一個FKSupport屬性。 加入FKSupport=True;我的連接字符串後,它返回此:

'Driver={SQLite3 ODBCDriver};Database=C:\Users\Staples\Documents\SQLLiteTest.s3db;StepAPI=;SyncPragma=;NoTXN=;Timeout=;ShortNames=;LongNames=;NoCreat=;NoWCHAR=;FKSupport=True;JournalMode=;OEMCP=;LoadExt=;BigInt=;PWD=' 

瞧!外鍵約束被強制執行。

-1
In C++ store app the following code helped me to enable PRAGMA foreign_keys 
sqlite3_stmt* stmt; 
sqlite3_prepare(db, "PRAGMA foreign_keys = ON;", -1, &stmt, 0); 
sqlite3_step(stmt); 

I called this after creating db using the call of 

int rc = sqlite3_open16(path->Data(), &db);