Включение ограничений внешнего ключа в SQLite - PullRequest
32 голосов
/ 23 ноября 2010

Я использую SQLite с C # и у меня есть некоторые таблицы с определенными внешними ключами.

Теперь я знаю, что по умолчанию ограничения внешнего ключа не применяются в SQLite, но я хотел бы включить их.

Возможно ли это сделать с помощью кода? Я посмотрел связанный вопрос , но я не уверен, как это сделать с помощью кода C #. Я использую последний плагин SQLite, доступный для Visual Studio 2008, для разработки моих таблиц.

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

Мне нужно, чтобы это изменение сохранялось при повторном открытии соединения. Возможно ли это?

Ответы [ 8 ]

54 голосов
/ 21 июня 2011

Наконец-то понял это из этого поста .Параметр PRAGMA foreign_key не сохраняется, но вы можете устанавливать его каждый раз, когда устанавливается соединение в ConnectionString .Это позволяет использовать табличные адаптеры Visual Studio.

  1. Убедитесь, что у вас установлена ​​ последняя версия (1.0.73.0) system.data.sqlite (1.0.66.0 не будет работать).
  2. Измените ConnectionString на data source=C:\Dbs\myDb.db;foreign keys=true; (замените C: \ Dbs \ myDb.db вашей базой данных sqlite).
6 голосов
/ 23 ноября 2010

Включите прагму:

PRAGMA foreign_keys = ON;

Вы можете выполнить это так же, как и любой другой оператор SQL.

3 голосов
/ 31 января 2013

Я тоже боролся с этой проблемой.Я решил исследовать полную строку подключения, сгенерированную в 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='

И вуаля!соблюдаются ограничения внешнего ключа.

3 голосов
/ 21 декабря 2011

Другое решение состоит в том, чтобы делать 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, вы можете использовать его повторно.

2 голосов
/ 23 ноября 2010

Они должны предоставить информацию, которую вы ищете:

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 голос
/ 23 ноября 2010

Добавить в строку подключения: ";EnforceFKConstraints=Yes|True|1;"

1 голос
/ 23 ноября 2010

Похоже, что вы можете просто выполнить команду SQL PRAGMA foreign_keys = ON; для вашего соединения с БД, как если бы вы были оператором Select или Update. Хотя вы должны убедиться, что ваш SQLite был скомпилирован с внешними ключами и тому подобным. Смотри Здесь .

0 голосов
/ 01 февраля 2013
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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...