[英]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.