Entity:
public class Page
{
//...
public virtual Page Parent { get; set; }
}
Need to set Parent field to null. Tried this, but no luck:
// Existing entity
Page pageAttached = db.Pages.First(x => x.Id == page.Id);
db.Entry(pageAttached).CurrentValues.SetValues(page);
if (model.ParentId != null)
pageAttached.Parent = db.Pages.First(x => x.Id == model.ParentId);
else
pageAttached.Parent = null; //does nothing
db.SaveChanges();
Parentis not a “complex field”, it is a “Navigation Property”.Does it work if you do this?
Response to comment 1
No, I meant
.Include(x => x.Parent). I prefer strongly-typing using the lambda overload. Keeps magic strings out of the code.The reason this works is because DbContext uses dynamically generated proxy classes for lazy loading. When you only query for
.First(x => x.Id == page.Id), the object returned is really a class that implements yourPageentity as its base class. (This is why collection and navigation properties have to be markedvirtual, so they can be overridden in the dynamic proxies.) Furthermore, the dynamically generated proxy has a null Parent reference, even if there is a parent in the db.It is not until the Parent property get method is invoked that EF hits the db to lazily load the parent. This is when it finds out whether the db actually has a null or non-null Parent property. So, when you set
.Parent = nullbefore the parent is actually lazily loaded, EF does nothing because it’s already null.The code I suggested uses
.Includeto eager load the Parent property. This means that the db gets both the child + its parent in a single db call. Now when you set null, the DbContext will track the change and remove the relationship during your next SaveChanges.