Создаем портфолио за 1 месяц
К концу месяца: 4 классных проекта в вашем портфолио! Стоимость: 100$. Подробности...
⊗csSpRlFk 426 of 509 menu
◀ ▶

Внешний ключ SQLite в C#

Примеры раздела используют SQLite через пакет в файле проекта:

<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net10.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.Data.Sqlite" Version="10.0.14" /> </ItemGroup> </Project>

Ограничение FOREIGN KEY задает ссылку зависимой таблицы на первичный ключ родителя.

В SQLite проверка срабатывает только после PRAGMA foreign_keys = ON на соединении. Таблица складов и ячеек с явной ссылкой на родителя создается ниже. Затем вставляют склад "W1" и ячейку "A-01". Печатают, сколько строк добавила последняя вставка:

using Microsoft.Data.Sqlite; string dbPath = "fk_bins.db"; if (File.Exists(dbPath)) { File.Delete(dbPath); } using SqliteConnection db = new($"Data Source={dbPath}"); db.Open(); using (SqliteCommand pragma = db.CreateCommand()) { pragma.CommandText = "PRAGMA foreign_keys = ON"; pragma.ExecuteNonQuery(); } using (SqliteCommand cmd = db.CreateCommand()) { cmd.CommandText = "CREATE TABLE IF NOT EXISTS warehouses (id INTEGER PRIMARY KEY, code TEXT NOT NULL)"; cmd.ExecuteNonQuery(); } using (SqliteCommand cmd = db.CreateCommand()) { cmd.CommandText = "CREATE TABLE IF NOT EXISTS bins (id INTEGER PRIMARY KEY, warehouse_id INTEGER NOT NULL, label TEXT NOT NULL, FOREIGN KEY (warehouse_id) REFERENCES warehouses (id))"; cmd.ExecuteNonQuery(); } using (SqliteCommand cmd = db.CreateCommand()) { cmd.CommandText = "INSERT INTO warehouses (code) VALUES ($p1)"; cmd.Parameters.AddWithValue("$p1", "W1"); cmd.ExecuteNonQuery(); } using (SqliteCommand cmd = db.CreateCommand()) { cmd.CommandText = "INSERT INTO bins (warehouse_id, label) VALUES ($p1, $p2)"; cmd.Parameters.AddWithValue("$p1", 1); cmd.Parameters.AddWithValue("$p2", "A-01"); Console.WriteLine(cmd.ExecuteNonQuery()); // выведет 1 }

Число в "warehouse_id" должно совпадать с существующим "id" склада. Иначе шаг вставки приведет к исключению SqliteException. Номер 99 ни одному складу не принадлежит, исключение перехватывают и пишут в консоль "rejected":

using Microsoft.Data.Sqlite; string dbPath = "fk_bins.db"; if (File.Exists(dbPath)) { File.Delete(dbPath); } using SqliteConnection db = new($"Data Source={dbPath}"); db.Open(); using (SqliteCommand pragma = db.CreateCommand()) { pragma.CommandText = "PRAGMA foreign_keys = ON"; pragma.ExecuteNonQuery(); } using (SqliteCommand cmd = db.CreateCommand()) { cmd.CommandText = "CREATE TABLE IF NOT EXISTS warehouses (id INTEGER PRIMARY KEY, code TEXT NOT NULL)"; cmd.ExecuteNonQuery(); } using (SqliteCommand cmd = db.CreateCommand()) { cmd.CommandText = "CREATE TABLE IF NOT EXISTS bins (id INTEGER PRIMARY KEY, warehouse_id INTEGER NOT NULL, label TEXT NOT NULL, FOREIGN KEY (warehouse_id) REFERENCES warehouses (id))"; cmd.ExecuteNonQuery(); } using (SqliteCommand cmd = db.CreateCommand()) { cmd.CommandText = "INSERT INTO bins (warehouse_id, label) VALUES ($p1, $p2)"; cmd.Parameters.AddWithValue("$p1", 99); cmd.Parameters.AddWithValue("$p2", "ghost"); try { cmd.ExecuteNonQuery(); } catch (SqliteException) { Console.WriteLine("rejected"); } // выведет "rejected" }

В новой базе "fk_docks.db" создайте причалы и лодки: у каждой лодки должен быть существующий причал. Добавьте причал "D-1" и лодку "B-12", затем выведите метку лодки из таблицы.

Попробуйте привязать лодку к несуществующему причалу. Если операция не прошла, выведите "bad link".

← →
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить