Как включить каскадное удаление внешнего ключа по умолчанию в SQLite? - PullRequest
7 голосов
/ 13 февраля 2011

SQLite v3.7.5

Есть ли способ включить Внешние ключи SQLite с включенным по умолчанию cascade delete?С учетом следующего примера:

CREATE TABLE [Parent] (
[ParentId] INTEGER  NOT NULL PRIMARY KEY AUTOINCREMENT,
[Name] VARCHAR(50)  UNIQUE NOT NULL
);

CREATE TABLE [Child] (
[ChildId] INTEGER  PRIMARY KEY AUTOINCREMENT NOT NULL,
[ParentId] INTEGER  NOT NULL,
[Name] VARCHAR(50)  NOT NULL,
FOREIGN KEY(ChildId) REFERENCES Child(ParentId) ON DELETE CASCADE
);

Единственный способ, которым я смог включить каскадное удаление, - это выполнить команду PRAGMA foreign_keys = true перед транзакцией:

using( var conn = new SQLiteConnection( _conn ) )
{
    conn.Open();
    var pragma = new SQLiteCommand( "PRAGMA foreign_keys = true;", conn );
    pragma.ExecuteNonQuery();

    var cmd = new SQLiteCommand( "Delete from Parent where ParentId = 1", conn );
    cmd.ExecuteNonQuery();
}

Есть липараметр на уровне базы данных, который можно настроить вместо необходимости вызывать команду pragma перед каждой транзакцией?

Я видел триггеры для включения каскадного удаления, но ищу что-то, что просто включило бы PRAGMA foreign_keys = true на уровне базы данных.

Ответы [ 3 ]

4 голосов
/ 13 февраля 2011

System.Data.SQLite 1.0.66 не имеет его, но в версии репозитория они обновлены до sqlite 3.7.4 и создали новый атрибут строки подключения «Внешние ключи». Кто знает, когда это будет выпущено официально? Таким образом, вы можете установить это в строке подключения. Проект живет здесь и сейчас: http://system.data.sqlite.org/index.html/doc/trunk/www/index.wiki

3 голосов
/ 13 февраля 2011

Нет, даже с опциями времени компиляции.

Пока единственный способ - использовать pragma foreign_keys=on во время выполнения.Особая опасность заключается в том, что каждое приложение, которое касается базы данных, должно это делать.

Если конкретное приложение не выполняет этот прагматический оператор, оно может вставить данные, которые нарушат ограничения внешнего ключа, и другие приложения не узнают об этом.То есть включение внешних ключей не предупреждает вас о существующих данных, которые нарушают ограничение.

1 голос
/ 13 февраля 2011

Нет, в настоящее время нет способа (для обратной совместимости).См. Ссылку, которую вы указали в разделе (2):

Ограничения внешнего ключа по умолчанию отключены (для обратной совместимости), поэтому должны быть включены отдельно для каждого соединения с базой данных отдельно.

Однако в будущем это может измениться:

(Обратите внимание, однако, что будущие выпуски SQLite могут измениться, так что ограничения внешнего ключа включены по умолчанию. Внимательные разработчики не будут делать никаких предположений относительнонезависимо от того, включены ли внешние ключи по умолчанию, но вместо этого они будут включать или отключать их по мере необходимости.)

...