【问题标题】:How to get auto increment identity column working如何使自动增量标识列工作
【发布时间】:2022-12-10 12:26:18
【问题描述】:

我们正在使用 EF Core,但我们也将 ef 核心数据库升级到最新版本。在 Postegres 上有一张表:

CREATE TABLE "DatabaseVersion"  
( 
    "DatabaseVersionId" integer NOT NULL GENERATED BY DEFAULT AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ) PRIMARY KEY, 
    "Version"     varchar(20) NOT NULL,  
    "VersionDate" timestamptz NULL DEFAULT Now(), 
    "Description" varchar(2000) NULL, 
    "AppliedDate" timestamptz NULL DEFAULT Now()
);

在 PgAdmin 中,我创建了一个数据库和这个表,然后我使用以下命令插入到表中进行测试:

INSERT INTO "DatabaseVersion" ("Version") 
VALUES ('1.0.0.0');

然后我输入了第一行,然后我可以更改插入语句中的版本并插入更多行。每行都有一个唯一的DatabaseVersionId

但是,当我运行升级并尝试使用 EF Core 插入值时,出现异常

重复键值违反唯一约束

我创建了一个新数据库来查看 EF Core 如何定义密钥,它是:

GENERATED BY DEFAULT AS IDENTITY (INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1).

我向其中添加了主键以避免向我们的旧脚本添加大量主键约束。

我们的更新代码显示在这里(T 将是 DatabaseVersion):

var dbSet = context.Set<T> ();

var id = GetKey (context, item);

if (id == 0)
{
    dbSet.Add (item);
}
else
{
    var p = dbSet.Find (id);
    dbSet.Attach (p);

    var a = context.Entry (p);

    if (a != null)
        a.CurrentValues.SetValues (item);
}

context.SaveChanges ();

需要对旧脚本做些什么才能使身份主键起作用?

或者这甚至是问题所在?我不是 postgres 专家。

我们的数据库升级使用脚本直到达到某个版本,然后我们运行每个migration individually。 EF Core 发现自己不会运行初始创建迁移,但它仍然会在 __EFMigrationsHistory 表中添加一个条目,这很棒。

更新

在我的搜索中,我找到了这个question。在我们更新和创建新数据库期间,我们插入的数据已经设置了主键,因此使用 postgresql 序列不会更新,并且在您第一次插入时会出现重复键异常。要在创建或升级数据库后解决此问题,您可以使用以下脚本:

                @"SELECT setval( 
                  (SELECT pg_get_serial_sequence( '""<%SchemaName%>"".""<%TableName%>""', '<%KeyName%>')),
                  (SELECT MAX(""<%KeyName%>"") from ""<%SchemaName%>"".""<%TableName%>""),
                  true );";

在带有表和主键名称的循环中使用它,可以将所有序列设置为其正确的值。

【问题讨论】:

  • 请注意,为什么是dbSet.Attach (p);?实体已附加。
  • 我们正在使用断开连接的实体,因此我们需要附加
  • dbSet.Find 返回跟踪的实体。
  • 是的,但我们已断开连接,因此未被跟踪

标签: entity-framework-core npgsql


【解决方案1】:

MS SQL Server 使用 IDENTITY 关键字来执行自动递增功能。在上面的示例中,IDENTITY 的起始值为 1,每条新记录都会递增 1。提示:要指定“Person id”列应从值 10 开始并递增 5,请将其更改为 IDENTITY(10,5) 。

【讨论】:

  • 这是 PostgreSQL 的问题。
猜你喜欢
  • 1970-01-01
  • 2018-07-30
  • 2012-06-06
  • 2014-01-27
  • 1970-01-01
  • 1970-01-01
  • 2011-06-01
  • 1970-01-01
相关资源
最近更新 更多