【问题标题】:Unable to add new user claim due to constraint conflict of primary key由于主键约束冲突,无法添加新用户声明
【发布时间】:2020-03-27 05:43:17
【问题描述】:

我有一个使用 Oracle 数据库的 net core web app net core 3.1。这些表是使用 MS.EntityFrameworkCore.Tools('add-migration' & '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 BY DEFAULT ON NULL,整数不可为空。

我如何从这里开始创建用户声明?

请忽略混合大小写、系统架构、引号等。

【问题讨论】:

  • 不是这个问题的原因,但我一直发现在 orracle 中使用 " 围绕 MiXeDcAsE 列名会导致其他地方最令人头疼的问题。每次都使用不区分大小写的列名
  • 尝试回到Core2.0。每个人都在 Core 3.0 和 3.1 中遇到 Entity 问题。
  • @CaiusJard 和 Littlefoot,要点(尽管 SQL 代码只是从 SQL Developer 表的 SQL 选项卡中复制出来的)。 @jdweng,你一定是在开玩笑。既然 MS.EFC.Tools 是 2.2.6 ,它不应该有点核心 2.0 吗?
  • 我不知道“每个人”是否是一个公平的评论——我们的 ef 3.x 项目没有任何重大问题。不过,我们不使用 aspnet 会员资格。

标签: c# oracle constraints add


【解决方案1】:

默认生成,同时手动提供其值:

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

如果您省略 ID:

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

始终生成;手动提供的 ID 值:

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

所以 - 不要提供 ID,让 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 数据库中的特殊用户,他们拥有它,并且除了 DBA 维护数据库时,不应使用它。在任何这些模式中创建自己的对象是/可能是一个巨大的错误。如果你做错了什么,你可能会破坏数据库。
  • 双引号(Caius Jardas 已评论):不要在 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 中忘记双引号。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-11
    • 1970-01-01
    • 2011-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-31
    • 2020-09-26
    相关资源
    最近更新 更多