Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This is a very big problem. What actually happens in your code is this:</p> <ul> <li>You load <code>Parent</code> from the database and get an attached entity</li> <li>You replace its child collection with new collection of detached children</li> <li>You save changes but during this operation all children are considered as <strong>added</strong> becasue EF didn't know about them till this time. So EF tries to set null to foreign key of old children and insert all new children => duplicate rows.</li> </ul> <p>Now the solution really depends on what you want to do and how would you like to do it? </p> <p>If you are using ASP.NET MVC you can try to use <a href="https://stackoverflow.com/questions/4653834/asp-net-mvc-ef4-poco-repository-how-to-update-relationships">UpdateModel or TryUpdateModel</a>.</p> <p>If you want just update existing children manually, you can simply do something like:</p> <pre><code>foreach (var child in modifiedParent.ChildItems) { context.Childs.Attach(child); context.Entry(child).State = EntityState.Modified; } context.SaveChanges(); </code></pre> <p>Attaching is actually not needed (setting the state to <code>Modified</code> will also attach the entity) but I like it because it makes the process more obvious.</p> <p>If you want to modify existing, delete existing and insert new childs you must do something like:</p> <pre><code>var parent = context.Parents.GetById(1); // Make sure that childs are loaded as well foreach(var child in modifiedParent.ChildItems) { var attachedChild = FindChild(parent, child.Id); if (attachedChild != null) { // Existing child - apply new values context.Entry(attachedChild).CurrentValues.SetValues(child); } else { // New child // Don't insert original object. It will attach whole detached graph parent.ChildItems.Add(child.Clone()); } } // Now you must delete all entities present in parent.ChildItems but missing // in modifiedParent.ChildItems // ToList should make copy of the collection because we can't modify collection // iterated by foreach foreach(var child in parent.ChildItems.ToList()) { var detachedChild = FindChild(modifiedParent, child.Id); if (detachedChild == null) { parent.ChildItems.Remove(child); context.Childs.Remove(child); } } context.SaveChanges(); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload