Подтвердить что ты не робот

Включение ограничений внешнего ключа в SQLite

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

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

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

PRAGMA foreign_keys = ON;

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

Ответ 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='

И вуаля! нарушены внешние ограничения.

Ответ 4

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

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

Ответ 5

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

Ответ 6

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

Ответ 7

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

Ответ 8

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);