Невозможно добавить новую заявку пользователя из-за конфликта ограничений первичного ключа - PullRequest
0 голосов
/ 27 марта 2020

У меня есть net core web app net core 3.1, использующее Oracle базу данных. Таблицы создаются с использованием MS.EntityFrameworkCore.Tools (команды «add -igration» и «update-database»). Автоматически сгенерированные таблицы, AspNetUserClaims и AspNetRoleClaims, используют автоматическое создание идентификаторов Oracle.

У меня проблема с данным кодом, я просто не могу добавить новую заявку пользователя из-за конфликт ограничений.

OracleException: ORA-00001: уникальное ограничение (SYSTEM.PK_AspNetUserClaims) нарушено.

SQL для таблицы:

CREATE TABLE "SYSTEM"."AspNetUserClaims" 
(   
    "Id" NUMBER(10,0) GENERATED BY DEFAULT AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER  NOCYCLE  NOKEEP  NOSCALE  NOT NULL ENABLE, 
    "UserId" NVARCHAR2(450) NOT NULL ENABLE, 
    "ClaimType" NVARCHAR2(2000), 
    "ClaimValue" VARCHAR2(3000 CHAR), 
     CONSTRAINT "PK_AspNetUserClaims" PRIMARY KEY ("Id")
     ......
)

C# код:

IdentityUserClaim<string> userClaim = new IdentityUserClaim<string> { UserId = user.Id, ClaimType = "WT", ClaimValue = JsonConvert.SerializeObject(jsonWebToken) };
//// var last = await _context.UserClaims.LastOrDefaultAsync(); // dumb workaround
//// userClaim.Id = last == null ? 1 : last.Id + 1;
await _context.UserClaims.AddAsync(userClaim);
  1. ВСЕГДА, попытка вставить значение приведет к ошибке, но id является целым числом со значением 0 по умолчанию.

  2. GENERATED DEFAULT, генерируется, если значение не указано, как и выше, целое число равно 0 по умолчанию.

  3. GENERATED DEFAULT ON NULL, целое число не nullable.

Как я могу приступить к созданию заявки от пользователя с этого момента?

Пожалуйста, игнорируйте смешанный регистр, системную схему, цитаты или что нет.

1 Ответ

0 голосов
/ 27 марта 2020

Генерируется по умолчанию с указанием его значения вручную:

SQL> create table test(id number generated by default as identity primary key, name varchar2(10));

Table created.

SQL> insert into test (id, name) values (1, 'Little');

1 row created.

SQL> insert into test (id, name) values (1, 'Foot');
insert into test (id, name) values (1, 'Foot')
*
ERROR at line 1:
ORA-00001: unique constraint (DP_4005.SYS_C001685565) violated

Если вы опустите идентификатор:

SQL> insert into test (name) values ('Foot');
insert into test (name) values ('Foot')
*
ERROR at line 1:
ORA-00001: unique constraint (DP_4005.SYS_C001685571) violated

Генерируется всегда; Значение идентификатора, предоставленное вручную:

SQL> create table test(id number generated always as identity primary key, name varchar2(10));

Table created.

SQL> insert into test (id, name) values (1, 'Little');
insert into test (id, name) values (1, 'Little')
                  *
ERROR at line 1:
ORA-32795: cannot insert into a generated always identity column

Итак - не предоставляйте идентификатор, позвольте Oracle обработать его:

SQL> insert into test (name) values ('Little');

1 row created.

SQL> insert into test (name) values ('Foot');

1 row created.

SQL> select * From test;

        ID NAME
---------- ----------
         1 Little
         2 Foot

Заключение? Пусть база данных обрабатывает столбцы, которые должны быть сгенерированы; не указывайте эти значения вручную.


Кроме того, первая отправленная вами строка:

CREATE TABLE "SYSTEM"."AspNetUserClaims" 

содержит 2 "ошибки", которых вы бы хотели избежать:

  • SYSTEM, как и SYS, являются специальными пользователями в базе данных Oracle, они владеют ею и должны не использоваться, за исключением администраторов баз данных при ведении базы данных. Создание ваших собственных объектов в любой из этих схем является / может быть ОГРОМНОЙ ошибкой. Если вы делаете что-то не так, вы можете уничтожить базу данных.
  • двойные кавычки (Гай Джардас уже прокомментировал): не используйте их в Oracle. Вы можете использовать любой регистр букв, который хотите, но имена объектов по умолчанию будут прописными.

См. Несколько примеров:

SQL> create table TesT (nAME varCHAr2(10));

Table created.

SQL> select table_name, column_name from user_tab_columns where table_name = 'TEST';

TABLE_NAME           COLUMN_NAME
-------------------- --------------------
TEST                 NAME

SQL> select NamE from TEst;

no rows selected

Но с двойными кавычками вы должны каждый раз сопоставлять регистр букв (и, конечно, каждый раз использовать двойные кавычки):

SQL> create table "TesT" ("nAME" varchar2(10));

Table created.

SQL> select table_name, column_name from user_tab_columns where table_name = 'TesT';

TABLE_NAME           COLUMN_NAME
-------------------- --------------------
TesT                 nAME

SQL> select * From test;
select * From test
              *
ERROR at line 1:
ORA-00942: table or view does not exist


SQL> select name from "test";
select name from "test"
                 *
ERROR at line 1:
ORA-00942: table or view does not exist


SQL> select name from "TesT";
select name from "TesT"
       *
ERROR at line 1:
ORA-00904: "NAME": invalid identifier


SQL> select "nAME" from "TesT";

no rows selected

SQL>

Так что - забудьте о двойных кавычках, находясь в Oracle.

...