@Fly3110
web developer

Как в Entity Frameword 6 корректно обновить коллекцию «детей»?

Есть класс Parent

public class Parent
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int? Id { get; set; }        
    
    public ICollection<Child> Children{ get; set; } 
}


и класс Child

public class Child
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int? Id { get; set; }
    
    [ForeignKey(nameof(Parent))]
    public int ParentId{ get; set; }
    public virtual Parent Parent{ get; set; }
}


Мне надо у родителя заменить имеющуюся коллекцию детей на новую, причем новая получена маппингом из коллекции DTO (ValueObjects).
При этом, если "ребенок" у родителя уже есть, его трогать не нужно, если его нет, его нужно добавить. Ну, и если существующий ребенок отсутствует в новой коллекции, его нужно удалить.

Попытка "в лоб" не проходит.
var children = ChildrenDTO.Select(mapper.Map<Child>);
using (var dbContext= new AppDbContext())
{
    var pulledParent = quoteMonkeyDbContext.Parents
                .Include(rp => rp.Children)
                .First(rp => rp.Id == Parent.Id);
                
    pulledParent .Children= children .ToList();
    dbContext.SaveChanges();
}


Нарываюсь на исключение:
System.InvalidOperationException: Multiplicity constraint violated. The role 'Child_Parent_Target' of the relationship 'MyAssembly.Persistence.Child_Parent' has multiplicity 1 or 0..1.


Я понимаю, что это происходит из-за того, что EF не пытается смотреть, какие уже есть дети у родителя, а в лоб пытается добавить новых. Если я руками сравниваю имеющиеся списки, нужных удаляю, имеющихся не трогаю и оставляю только тех, кого нужно добавить, то все работает.

Но меня не покидает ощущение, что я делаю то, что уже предусмотрено, просто я не умею это правильно делать :)
  • Вопрос задан
  • 57 просмотров
Решения вопроса 1
sarapinit
@sarapinit Куратор тега C#
Точу водой камень
У EntityFramework есть трекер изменений который отслеживает состояние сущностей чтобы понимать что с ними делать при обновлении. В вашем случае все ваши замапленные объекты попадают в состояние Added. Поэтому EF пытается их вставить. Вам нужно сделать исключить из вашей коллекции объекты с уже существующими в БД идентификаторами и вставлять только те, которых нет.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы