Упрощенные версии моих объектов:
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;}
}
Из тела запроса (из внешнего интерфейса) приходит следующий объект (снова очень упрощенный):
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
У меня Generi c Шаблон репозитория (архитектура), поэтому I l oop через Список добавленных сущностей и вызывает conext.Set.Add (entity), I l oop через Modified и вызывает Update, а I l oop через удаленные ID и вызовите Remove по ID.
Проблема / вопрос:
Проблема в том, что я обращаюсь к CV с помощью .Include (cv => cv.Certificate) и всех связанных с этим данных путь. Затем я вызываю 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 (сертификат) или что-то в этом роде, у меня есть доступ только к DbSet напрямую. Пытался сделать {context_name}.Entry(entity).State = EntityState.Detached;
Еще пробовал AsNoTracking
.
А как насчет «многие ко многим»? Там еще хуже. Существует более глубокое управление вложением и отслеживанием.
А что насчет этого?
Как лучше всего обновить связанные данные объекта (и связанные данные связанных данных) в EF Core 3+?
Следует ли мне использовать {context_name}.Entry(entity).CurrentValues.SetValues(modifiedEntity);
вместо Update(modifiedEntity);
?