Автоинкремент SqLite для одного из его составных ключей - PullRequest
0 голосов
/ 05 декабря 2018

SqLite Composite Keys

В SQL Server IDENTITY(1,1) установлены следующие столбцы с автоинкрементом, и я хотел аналогичного поведения в SqLite: Tenant. TenantID , Project. ProjectID и Credits. CreditsID .Хотя в SqLite есть AUTOINCREMENT, и я попробовал его, но он работает только для таблиц, имеющих только 1 первичный ключ.Я попробовал следующее тестирование:

Кстати, я использовал Microsoft.EntityFrameworkCore.Sqlite 2.1.4 для этого тестирования

Явно назначьте значение для этих столбцов с автоматическим приращением:

  1. Tenant.TenantID

    a.-99 : остается -99 после сохранения

    b.0 : становится 1 после сохранения

    c.99 : остается 99 после сохранения

  2. Для Project.ProjectID & Credits.CreditsID

    a.Значения -99 и 99 остаются неизменными после сохранения изменений в DbContext.Но я не хочу явно назначать эти значения, потому что в моем DbContext есть куча тестовых данных.

    b.Присвоение явного значения 0 приводит к этой ошибке: Microsoft.Data.Sqlite.SqliteException : SQLite Error 19: 'NOT NULL constraint failed: Credits.CreditsID'.

Я действительно был бы благодарен за кого-то, кто может помочь мне с этим.Это были дни, когда это беспокоит меня.

1 Ответ

0 голосов
/ 06 декабря 2018

С SQLite вы, вероятно, не хотите использовать AUTOINCREMENT, это фактически не устанавливает столбец в инкрементное значение, а устанавливает ограничение, согласно которому значение, если оно не установлено явно, должно иметь более высокое значение, чем было выделено.

Простое определение столбца с помощью INTEGER PRIMARY KEY устанавливает столбец в инкремент, если явно не задано значение.Отмечая, что в таблице может быть только один такой столбец.

  • Обратите внимание, что SQLite НЕ гарантирует увеличение на 1, а гарантирует уникальный идентификатор, который является целым числом и может даже быть меньше (только после и id9223372036854775807). Автоинкремент SQLite .В этом случае использование AUTOINCREMENT не удастся с исключением SQLIte Full, в то время как без AUTOINCREMENT SQLite попытается найти неиспользуемый идентификатор.

Глядя на вашу диаграмму, я считаю, что таблице Credits не понадобится TennantID какэто доступно через Проект, ссылающийся на Теннант.

Игнорирование, отличное от столбцов, составляющих отношения (также добавление необязательных ограничений внешнего ключа, которые обеспечат ссылочную целостность), тогда я полагаю, что вы могли бы использовать что-то подобноеиз: -

DROP TABLE IF EXISTS credits;
DROP TABLE IF EXISTS project;
DROP TABLE IF EXISTS tennant;
CREATE TABLE IF NOT EXISTS tennant (tennant_id INTEGER PRIMARY KEY, Name TEXT, other_columns);
CREATE TABLE IF NOT EXISTS project (project_id INTEGER PRIMARY KEY, tennant_reference REFERENCES tennant(tennant_id), Title);
CREATE TABLE IF NOT EXISTS credits (credit_id INTEGER PRIMARY KEY, project_reference INTEGER REFERENCES project(project_id), other_columns TEXT);
CREATE TABLE IF NOT EXISTS creidts (credit_id INTEGER PRIMARY KEY, project_reference INTEGER, other_columns);
INSERT INTO tennant VALUES(1,'Fred','other data'); -- Explicit ID 1
INSERT INTO tennant (Name,other_columns) VALUES('Mary','Mary''s other data'),('Anne','Anne''s other data'); -- Implicit ID 's (2 and 3 most likely)
INSERT INTO project VALUES (99,1,'Project001 for Fred'); --  Explicit Project ID 99 - tennant 1 = Fred
INSERT INTO project (tennant_reference,Title) VALUES(1,'Project002 for Fred'),(2,'Project003 for Mary'),(3,'Project004 for Anne'); -- 3 implicit project id's 100,101 and 102 (most likely)

-- Result 1
SELECT * FROM project JOIN tennant ON tennant_reference = tennant.tennant_id;

INSERT INTO credits VALUES(199,99,'Other credit columns'); -- Explicit credit ID of 199 for Project001 (tennant implied) 
INSERT INTO credits VALUES(0,99,'Other credit colums credit_id = 0'); -- Explicit credit ID of 0 for Project002
INSERT INTO credits (project_reference,other_columns) VALUES (100,'for Project002'),(100,'another for Project002'),(102,'for Project004');

SELECT * FROM credits JOIN project ON project_reference = project_id JOIN tennant ON tennant_reference = tennant_id;
  • Это удаляет все существующие таблицы, чтобы упростить тестирование.
  • Затем создаются 3 таблицы.
  • Строки вставляются в явном видеи неявно (рекомендуемый путь) в таблицу Tennant, а затем в таблицу Project (обратите внимание, что строки, ссылающиеся на несуществующий tennant, не могут быть вставлены в таблицу Project из-за ограничения внешнего ключа)
  • Projectsвместе с деталями объединенных теннантазатем перечислены (см. Результаты)
  • Затем строки вставляются в таблицу кредитов с использованием явных и неявных кредитных идентификаторов (обратите внимание, что 199 явно определен, а затем 0).
  • Как вы можете видеть, когда идентификаторыавтоматически генерируются, они, как правило, на 1 больше, чем наибольшее значение, использованное на сегодняшний день.

Результаты

Первый запрос (Проект со связанным Tennant)

enter image description here

Кредиты второго запроса со связанным Проектом и соответствующим Теннантом

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...