复制实体时出现违规错误

getting a violation error while copying entities

我有以下实体项目天气具有以下结构

public class ProjectWeather
{
    [Key, ForeignKey("Project")]
    public string ProjectNumber { get; set; }
    [GraphQLIgnore]
    public virtual Project Project { get; set; }
    [ForeignKey("WeatherStation")]
    public string WeatherStationNumber { get; set; }
}

我还有其他实体 project 结构如下所示

public class Project : PatchEntityProperties
{
    [Key, GraphQLNonNullType]
    public string ProjectNumber { get; set; }
    public string Name { get; set; }
    public bool IsLocked { get; set; }
    public ProjectWeather Weather { get; set; } = new ();
}

我想做的是使用以下代码将一个项目信息复制到另一个项目中

   var cloneOfSourceProject = dbContext.Projects
        .AsNoTracking()
        .Where(a => a.ProjectNumber == sourceProjectNumber)
        .SingleOrDefault();

    // Tracked so we can remove existing project before adding copied entity
    var targetProject = dbContext.Projects
        .Where(a => a.ProjectNumber == targetProjectNumber)
        .SingleOrDefault();

    if (cloneOfSourceProject == default)
    {
        throw new ArgumentException($"The project with project number '{sourceProjectNumber}' does not exist; an invalid project cannot be copied.");
    }
    
    string targetProjectName;
    if (targetProject == default)
    {
        targetProjectName = dbContext.Projects.AsNoTracking().Where(a => a.Number == targetProjectNumber).SingleOrDefault()?.Name ?? "";
    }
    else
    {
        targetProjectName = targetProject.Name;
        dbContext.Remove(targetProject);
    }

    cloneOfSourceProject.ProjectNumber = targetProjectNumber;
    cloneOfSourceProject.Name = targetProjectName;
    dbContext.Add(cloneOfSourceProject);
    dbContext.SaveChanges();

但是在重复键值上出现错误违反了 PK_projectweather 项目天气的唯一约束,我不确定如何克服该错误,上面的代码有什么问题吗?我正在将 EFcore 与 postgresql 一起使用。

任何人都可以让我知道这方面的任何想法,非常感谢。

好的,我知道可能会发生什么。当您查询 cloneOfSourceProject 时,您指定的是 AsNoTracking()。这意味着附加到您正在查询的项目的 ProjectWeather 对象也会返回,但 EF Core 不会跟踪其身份。然后更改项目的 ProjectNumber 并保存它,因此 EF Core 会尝试保存整个对象及其 ProjectWeather(其 ProjectNumber 未更改)。这导致 postgres 使用已经存在的键写入新的 ProjectWeather 行,因此出现异常。

如果这是正确的,您只需在保存项目之前将 ProjectWeather 的密钥设置为新的 ProjectNumber 即可解决问题:

cloneOfSourceProject.Weather.ProjectNumber = targetProjectNumber;