首页 > 解决方案 > 实体的深层复制导致“实体类型‘X’上的属性‘Id’是键的一部分,因此不能修改或标记为已修改

问题描述

我有一对多的关系,我正在尝试复制它们。

var context = this._dbContextProvider.GetDbContext();

var parent = await context.Parents
            .Include(p => p.Childs)                
            .FirstOrDefaultAsync(p => p.Id == inputParentId);

var copiedParent = parent;
copiedParent.Id = Guid.Empty;

List<Child> c = new List<Child>();
foreach (var child in copiedCaptureTemplate.childs)
{
   var copiedChild = child;
   copiedChild.Id = Guid.Empty;
   copiedChild.ParentId = Guid.Empty;
   c.Add(copiedChild);
}

copiedParent.Childs = null;

var createdParent = await context.Parents.AddAsync(copiedParent);
context.SaveChanges();

//loop on list c to add on the new parentId's
//add that list to the createParent and SaveChanges

可能有更好的深度复制方法,但我认为这会奏效。但是,当我 addAsync 我得到错误:

实体类型“Child”的属性“Id”是键的一部分,因此不能修改或标记为已修改。要使用标识外键更改现有实体的主体,首先删除依赖项并调用“SaveChanges”,然后将依赖项与新主体关联。

实体 Parent 具有:

 public ICollection<Child> Childs { get; set; }

实体 Child 具有:

public virtual Guid ParentId { get; set; }
public Parent Parent{ get; set; }

PortalDbContext 有:

modelBuilder.Entity<Parent>()
   .HasMany(p => p.Childs)
   .WithOne(c => c.Parent)
   .HasForeignKey(c => c.ParentId);

标签: c#entity-framework-core

解决方案


我的解决方案是按照 Progman 的建议添加AsNoTracking ()

var parent = await context.Parents
        .Include(p => p.Childs)
        .AsNoTracking()
        .FirstOrDefaultAsync(p => p.Id == inputParentId);

推荐阅读