簡體   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