我正在开发一个 .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
并且不会尝试插入新的,从而避免违反主键约束?
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;
}
}
这解决了我的问题。