EF Core:处理 Nazione 实体上主键约束违规的 DbUpdateException

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

我正在开发一个 .NET 8 应用程序,使用 Entity Framework Core 进行 ORM、使用 AutoMapper 进行对象映射、使用 MediatR 进行 CQRS 模式实现。

我有两个实体,

Provincia
Nazione
,外键关系从
Provincia
Nazione
。该关系的建立是为了确保如果没有相应的
Provincia
Nazione
就不可能存在。以下是我的课程的简化版本:

public class Provincia : Entity<int>
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id_Provincia { get; set; }

    [Required]
    [Column("Cd_Nazione", TypeName = "char(2)")]
    public string Cd_Nazione { get; set; }

    [Key]
    [Required]
    [Column("Cd_Provincia", TypeName = "char(3)")]
    public string Cd_Provincia { get; set; }

    [Required]
    [Column("Descrizione", TypeName = "varchar(50)")]
    public string Descrizione { get; set; }

    [ForeignKey("Cd_Nazione")]
    [JsonIgnore]
    public virtual Nazione Nazione { get; set; }
}

纳粹级:

public class Nazione : Entity<int>
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Column("Id_Nazione", TypeName = "int")]
    public int Id_Nazione { get; set; }

    [Key]
    [Column("Cd_Nazione", TypeName = "char(2)")]
    [Required]
    public string Cd_Nazione { get; set; }

    [Column("Descrizione", TypeName = "varchar(50)")]
    [Required]
    public string Descrizione { get; set; }

    public virtual ICollection<Provincia> Provincia { get; set; }
}

CreateProvinceCommand
处理程序片段:

public async Task<CreateProvinceResponse> Handle(CreateProvinceCommand request, CancellationToken cancellationToken)
{
    await countryBusinessRules.CountryShouldBeExists(request.Cd_Nazione);
    await provinceBusinessRules.ProvinceCannotDuplicate(request.Cd_Provincia);
    
    Provincia? province = mapper.Map<Provincia>(request);
    var result = await provinceRepository.AddAsync(province);
    CreateProvinceResponse response = mapper.Map<CreateProvinceResponse>(result);

    return response;
}

当我尝试使用现有

Provincia
创建新的
Nazione
时,我遇到与
Microsoft.EntityFrameworkCore.DbUpdateException
实体上的主键约束违规相关的
Nazione

异常消息是:

违反主键约束“PK_Nazione”。无法在对象“dbo.Nazione”中插入重复的键

即使我尝试将

Cd_Nazione
与数据库中已存在的
Provincia
关联,也会发生这种情况。

public async Task CountryShouldBeExists(string cd_Nazione)
{
    cd_Nazione = cd_Nazione.ToLower();

    var result = await countryRepository
                           .AnyAsync(x => x.Cd_Nazione.ToLower().Equals(cd_Nazione), enableTracking: false);

    if (!result)
    {
        throw new BusinessException(CountryMessages.CountryNotFound);
    }
}

我很困惑为什么 EF Core 试图在给定

Nazione
的记录已经存在的情况下插入新的
Cd_Nazione
记录,从而导致主键约束违规。在对
Cd_Nazione
调用
AddAsync
之前,我已确保
Provincia
已正确传递并存在于数据库中。

有人遇到过类似的问题或者能发现我在这里可能做错了什么吗?如何确保 EF Core 识别现有的

Nazione
并且不会尝试插入新的,从而避免违反主键约束?

c# entity-framework-core
1个回答
0
投票
using Doing.Retail.Core.Persistence.Repositories;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json.Serialization;

namespace Doing.Retail.Domain.Entities;

public class Provincia : Entity<int>
{
    public int Id_Provincia { get; set; }
    public string Cd_Nazione { get; set; }
    public string Cd_Provincia { get; set; }
    public string Descrizione { get; set; }
    public virtual Nazione Nazione { get; set; } = null!;

    public Provincia()
    {
      
        Cd_Nazione = string.Empty;
        Cd_Provincia = string.Empty;
        Descrizione = string.Empty;
    }
    public Provincia(int id_Provincia, string cd_Nazione, string cd_Provincia, string descrizione) : this()
    {
        Id_Provincia = id_Provincia;
        Cd_Nazione = cd_Nazione;
        Cd_Provincia = cd_Provincia;
        Descrizione = descrizione;
    }
}

这解决了我的问题。

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