Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><code>CurrentValues.SetValues</code> only updates scalar properties but no related entities, so you must do the same for each related entity:</p> <pre><code>public Foo Edit(Foo newFoo) { var dbFoo = context.Foo .Include(x =&gt; x.SubFoo) .Include(x =&gt; x.AnotherSubFoo) .Single(c =&gt; c.Id == newFoo.Id); context.Entry(dbFoo).CurrentValues.SetValues(newFoo); context.Entry(dbFoo.SubFoo).CurrentValues.SetValues(newFoo.SubFoo); context.Entry(dbFoo.AnotherSubFoo).CurrentValues.SetValues(newFoo.AnotherSubFoo); context.SaveChanges(); return newFoo; } </code></pre> <p>If the relationship could have been removed altogether or have been created you also need to handle those cases explicitly:</p> <pre><code>public Foo Edit(Foo newFoo) { var dbFoo = context.Foo .Include(x =&gt; x.SubFoo) .Include(x =&gt; x.AnotherSubFoo) .Single(c =&gt; c.Id == newFoo.Id); context.Entry(dbFoo).CurrentValues.SetValues(newFoo); if (dbFoo.SubFoo != null) { if (newFoo.SubFoo != null) { if (dbFoo.SubFoo.Id == newFoo.SubFoo.Id) // no relationship change, only scalar prop. context.Entry(dbFoo.SubFoo).CurrentValues.SetValues(newFoo.SubFoo); else { // Relationship change // Attach assumes that newFoo.SubFoo is an existing entity context.SubFoos.Attach(newFoo.SubFoo); dbFoo.SubFoo = newFoo.SubFoo; } } else // relationship has been removed dbFoo.SubFoo = null; } else { if (newFoo.SubFoo != null) // relationship has been added { // Attach assumes that newFoo.SubFoo is an existing entity context.SubFoos.Attach(newFoo.SubFoo); dbFoo.SubFoo = newFoo.SubFoo; } // else -&gt; old and new SubFoo is null -&gt; nothing to do } // the same logic for AnotherSubFoo ... context.SaveChanges(); return newFoo; } </code></pre> <p>You eventually also need to set the state of the attached entities to <code>Modified</code> if the relationship has been changed <em>and</em> the scalar properties as well.</p> <p><strong>Edit</strong></p> <p>If - according to your comment - <code>Foo.SubFoo</code> is actually a collection and not only a reference you will need something like this to update the related entities:</p> <pre><code>public Foo Edit(Foo newFoo) { var dbFoo = context.Foo .Include(x =&gt; x.SubFoo) .Include(x =&gt; x.AnotherSubFoo) .Single(c =&gt; c.Id == newFoo.Id); // Update foo (works only for scalar properties) context.Entry(dbFoo).CurrentValues.SetValues(newFoo); // Delete subFoos from database that are not in the newFoo.SubFoo collection foreach (var dbSubFoo in dbFoo.SubFoo.ToList()) if (!newFoo.SubFoo.Any(s =&gt; s.Id == dbSubFoo.Id)) context.SubFoos.Remove(dbSubFoo); foreach (var newSubFoo in newFoo.SubFoo) { var dbSubFoo = dbFoo.SubFoo.SingleOrDefault(s =&gt; s.Id == newSubFoo.Id); if (dbSubFoo != null) // Update subFoos that are in the newFoo.SubFoo collection context.Entry(dbSubFoo).CurrentValues.SetValues(newSubFoo); else // Insert subFoos into the database that are not // in the dbFoo.subFoo collection dbFoo.SubFoo.Add(newSubFoo); } // and the same for AnotherSubFoo... db.SaveChanges(); return newFoo; } </code></pre>
 

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