A
A
Anton Ivanov2021-05-29 14:42:04
C++ / C#
Anton Ivanov, 2021-05-29 14:42:04

How to correctly update the collection of "children" in Entity Frameword 6?

There is a classParent

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


and classChild

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; }
}


I need to replace the parent's existing collection of children with a new one, and the new one is obtained by mapping from the DTO (ValueObjects) collection.
In this case, if the parent already has a "child", you do not need to touch it, if it does not exist, you need to add it. Well, if the existing child is not in the new collection, it must be deleted.

An attempt "on the forehead" does not work.
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();
}


I run into an exception:
System.InvalidOperationException: Multiplicity constraint violated. The role 'Child_Parent_Target' of the relationship 'MyAssembly.Persistence.Child_Parent' has multiplicity 1 or 0..1.


I understand that this is due to the fact that EF does not try to look at what children the parent already has, but tries to add new ones directly. If I manually compare the existing lists, delete the ones I need, leave the existing ones untouched and leave only those who need to be added, then everything works.

But I still have the feeling that I am doing what is already provided, I just don’t know how to do it right :)

Answer the question

In order to leave comments, you need to log in

1 answer(s)
I
Ilya, 2021-05-29
@Fly3110

EntityFramework has a change tracker that keeps track of the state of entities in order to understand what to do with them when updated. In your case, all your mapped objects end up in the Added state. So EF tries to insert them. You need to exclude from your collection objects with identifiers that already exist in the database and insert only those that do not exist.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question