繁体   English   中英

如何在 EF Core 3+ 中使用具有状态(修改、添加、删除)的请求/正文自定义对象更新具有相关数据(数组)的实体?

[英]How to update an entity with related data (arrays) from request/body custom objects with states (modified, added, removed) in EF Core 3+?

我的对象的简化版本:

public class CV 
{
  public int Id {get;set;}
  public string Name {get;set;}
  public List<Certificate> Certificates {get;set;}
  public List<Experience> Experiences {get;set;}
}
public class Certificate 
{
  public int Id {get;set;}
  public string Name {get;set;}
}
public class Experience 
{
  public int Id {get;set;}
  public string Name {get;set;}
  public List<SkillExperience> Skills {get;set;}
}
public class SkillExperience
{
  public int SkillId {get;set;}
  public int ExperienceId {get;set;}
  public bool isCore {get;set;}
}
public class Skill 
{
  public int Id {get;set;}
  public string Name {get;set;}
}

来自请求的正文(来自前端)来自以下 object (再次真正简化):

public class CvRequest 
{
  public int Id {get;set;}
  public string Name {get;set;}
  public CertificateRequest Certificates {get;set;}
  public ExperienceRequest Experiences {get;set;}
}
public class CertificateRequest
{
  public List<Certificate> AddedCertificates {get;set;}
  public List<Certificate> ModifiedCertificates {get;set;}
  public List<int> RemovedCertificateIDs {get;set;}
}
// the ExperienceRequest is a little more complex because it has a many-to-many relationship, so I won't show it
// but it's similar, the question is related to it, but it has the same pattern of modified/added/removed

我有通用存储库模式(架构),所以我循环通过添加的实体列表并调用 conext.Set.Add(entity),我循环通过修改并调用更新,我循环通过删除的 ID 并通过 ID 调用删除.

问题/问题:

问题是我用 .Include(cv => cv.Certificate) 访问 CV 和所有相关数据。 然后我调用cvRepository.Update(cvRequest.ToEntity<CV>()); 它可以工作,但是当我调用certificateRepository.Update(new Certificate(){...}); 它说:

System.InvalidOperationException: The instance of entity type 'Certificate' cannot be tracked because another instance with the key value '{Id: 5}' is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.

由于它是与已跟踪实体相关的数据,因此我无法自行更新它。 我不能 cv.Certificates.Update(certificate) 或类似的东西,我只能直接访问 DbSet。 我试图让{context_name}.Entry(entity).State = EntityState.Detached; 我也试过AsNoTracking

多对多呢? 那里更糟。 有更深层次的嵌套和跟踪管理。

那这个呢?

在 EF Core 3+ 中更新实体的相关数据(以及相关数据的相关数据)的最佳方法是什么?

我应该使用{context_name}.Entry(entity).CurrentValues.SetValues(modifiedEntity); 而不是Update(modifiedEntity); ?

我认为您遇到的问题是您尝试再次跟踪 ID=5 的证书,尽管它已经通过调用进行了跟踪

certificateRepository.Update(new Certificate(){...});

基本上它已经用.Include(cv => cv.Certificate)加载和跟踪了,你尝试通过创建一个新的 Object 并在你的存储库上调用更新来再次跟踪它。

在这种情况下,您可以操作与 cvRequest 一起加载的证书并调用 SaveChanges,而无需在新的 object 实体上显式调用“更新”。 EF Core 将为您管理跟踪并注意到它已更改并更新它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM