Вставьте значение «0» в столбец идентификаторов и позвольте ему автоматически сгенерировать идентификатор

Я использую приложение под названием AspNetZero (во многом похожее на AspNet Boilerplate) и создал в нем сценарий миграции.

Скрипт миграции выглядит так:

migrationBuilder.CreateTable(
    name: "ContractCustomer",
    columns: table => new
    {
        ContractId = table.Column<int>(nullable: false),
        CustomerId = table.Column<int>(nullable: false),
        Id = table.Column<int>(nullable: false).Annotation("SqlServer:Identity", "1, 1"),
        CreationTime = table.Column<DateTime>(nullable: false),
    },
    constraints: table =>
    {
        table.UniqueConstraint("UX", x => new {x.ContractId, x.VerzorgerId});
        table.PrimaryKey("PK_ContractVerzorger", x => x.Id);
    });

Таким образом, создается таблица с первичным ключом на Id, который автоматически увеличивается.

введите здесь описание изображения

Но дело в том, что с AspNetZero для вас все немного автоматизировано за кулисами. Когда я пытаюсь вставить Contract с ContractCustomer, я получаю следующую ошибку:

Не удается вставить явное значение для столбца идентификаторов в таблицу «ContractCustomer», если для параметра IDENTITY_INSERT установлено значение OFF.

Когда я использую SQL Server Profiler, я вижу, что он пытается выполнить следующий запрос:

INSERT INTO [ContractCustomer] ([Id], [ContractId], [CustomerId], [CreationTime])
VALUES (0, 2, 1, '2020-09-12 13:33:54.2629678');

Так что это явно устанавливает Id в 0. Но та часть, где он сохраняет изменения, происходит за кулисами.

Есть ли способ заставить SQL Server игнорировать 0 и позволить ему генерировать собственный номер Id? Или есть что-то, что я могу настроить в своем сценарии миграции, чтобы заставить это работать?


person Vivendi    schedule 12.09.2020    source источник


Ответы (1)


Один из способов быстро решить эту проблему — создать триггер INSTEAD OF. Затем просто удалите идентификатор и 0 из фактической INSERT, которая выполняется. Что-то вроде этого

drop trigger if exists trg_ContractCustomer_instead_of_ins;
go
create trigger trg_ContractCustomer_instead_of_ins on [ContractCustomer]
instead of insert
as
set nocount on;
if exists(select * from inserted)
    INSERT INTO [ContractCustomer] ([ContractId], [CustomerId], [CreationTime])
    select [ContractId], [CustomerId], [CreationTime] from inserted;
person SteveC    schedule 12.09.2020