使用 EF Core 和 Postgresql 添加时出现“重复键值违反唯一约束”错误

问题描述 投票:0回答:1

我正在尝试使我的应用程序能够使用 SQL Server 或 Postgresql。我的应用程序使用的是

Npgsql.EntityFrameworkCore.PostgreSQL
版本 8 和 EF Core 版本 8.01。

当我使用 Postgresql 并向表中添加一系列实体时,它失败并出现以下错误

[23505]错误:重复的键值违反了唯一约束

但是指向 SQL Server 的相同代码就可以了。该代码正在循环中将实体添加到列表中,然后尝试使用

AddRangeAsync
将它们添加到数据库中。

调用

SaveChangesAsync()
时会出现错误。我认为问题在于添加的实体的标识列的值全为零,并且代码试图将多个 Id 为零的实体添加到表中。

如果我通过 SQL 脚本在 PgAdmin 的 Postgresql 中添加这些实体之一,则会添加该实体,并且 Id 会正确递增。我尝试了各种解决方案,例如将

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
添加到实体类的
Id
属性,添加
entity.Property(e => e.Id).ValueGeneratedOnAdd()
,以及显式添加 Id 为零的实体。没有任何效果。

请帮忙。

代码:

await _dbContext.Database.ExecuteSqlInterpolatedAsync($"DELETE FROM dbo.PropertyStations WHERE (PropertyId = {property.Id})").ConfigureAwait(false);
await _dbContext.SaveChangesAsync().ConfigureAwait(false);

if (property.Stations != null && property.Stations.Any())
{
    List<PropertyStation> pss = new List<PropertyStation>();

    property.Stations.ForEach(s =>
    {
        PropertyStation ps = new PropertyStation()
        {
            PropertyId = prop.PropertyId,
            StationId = s.StationId
        };

        pss.Add(ps);
    });

    if (pss.Any())
    {
        await _dbContext.PropertyStations.AddRangeAsync(pss).ConfigureAwait(false);
        await _dbContext.SaveChangesAsync().ConfigureAwait(false);
    }
}

表定义:

CREATE TABLE IF NOT EXISTS dbo.propertystations
(
    id integer NOT NULL DEFAULT nextval('dbo.propertystations_id_seq'::regclass),
    propertyid integer NOT NULL,
    stationid integer NOT NULL,
    CONSTRAINT pk_propertystations PRIMARY KEY (id),
    CONSTRAINT fk_propertystations_properties 
        FOREIGN KEY (propertyid)
        REFERENCES dbo.properties (propertyid) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION,
    CONSTRAINT fk_propertystations_stations 
        FOREIGN KEY (stationid)
        REFERENCES dbo.stations (stationid) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
)

实体定义:

[Index(nameof(PropertyId), Name = "IX_PropertyStations")]
[Index(nameof(StationId), Name = "IX_PropertyStations_1")]
[Index(nameof(PropertyId), nameof(StationId), Name = "IX_PropertyStations_2", IsUnique = true)]
public partial class PropertyStation
{
    [Key]
    //[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public int PropertyId { get; set; }
    public int StationId { get; set; }
}
c# postgresql entity-framework-core npgsql
1个回答
0
投票

如果它对其他人有帮助,我将发布为我解决此问题的方法。

  1. 我将 Postgresql 数据库中的 Id 列从序列类型更改为身份类型(始终生成为 IDENTITY)。
  2. 我确保在我的 DbContext 中,具有上述标识列的每个实体都有以下内容:entity.Property(e => e.Id).UseIdentityAlwaysColumn();

完成此操作后,一切都按预期工作,就像使用 Sql Server 一样。

© www.soinside.com 2019 - 2024. All rights reserved.