I have an optional foreign key that I'm attempting to set to null. No matter what I've tried, on SaveChanges(), the update statement sets the foreign key to the previous value instead of null.
Simplified Child Class:
public class Child
{
[Key, Column(Order = 0), ScaffoldColumn(false)]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[ForeignKey("Parent")]
public int? ParentId { get; set; }
public virtual Parent Parent { get; set; }
}
Simplified Parent Class:
public class Parent
{
[Key, Column(Order = 0), ScaffoldColumn(false)]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public virtual ICollection<Child> Children { get; set; }
}
Things I've tried:
- Load the Child object and set the ParentId null and set the Parent to null
- Load the Child object and set the ParentId null and force the entity state to be modified
- Load the Child object including the Parent object, then setting the values to null and forcing the entity state to be modified
- Load the Parent object, then the Child object and .Remove(child) from the Parent object
- Load the Parent object, then the Child object and .Remove(child) from the Parent and set the Child.ParentId to null and the Child.Parent to null.
Currently I have:
public void RemoveChildFromParent(int childId, int parentId)
{
Parent parent = _context.Parents.Include(x => x.Children).FirstOrDefault(u => u.Id == parentId);
Child child = parent.Children.SingleOrDefault(u => u.Id == childId);
parent.Children.Remove(child);
child.ParentId = null;
child.Parent = null;
child.StateOfEntity = StateOfEntity.Modified;
_context.ApplyStateChanges();
_context.SaveChanges();
}
On Save Changes, the SQL Update Statement still sets the ParentId on the Child object to the old value and I get this error:
System.InvalidOperationException was unhandled by user code
HResult=-2146233079
Message=The changes to the database were committed successfully, but an error occurred while updating the object context. The ObjectContext might be in an inconsistent state. Inner exception message: A referential integrity constraint violation occurred: The property values that define the referential constraints are not consistent between principal and dependent objects in the relationship.
Source=System.Data.Entity
StackTrace:
at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)
at System.Data.Entity.Internal.InternalContext.SaveChanges()
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
at System.Data.Entity.DbContext.SaveChanges()
at Insight.DataLayer.InsightContext.SaveChanges()
at Insight.DataLayer.ChildRepository.RemoveChildFromParent(Int32 childId, Int32 parentId)
at Insight.BusinessLayer.ParentManager.RemoveChild(Int32 id, Int32 parentId)
at Insight.PresentationLayer.Controllers.ParentController.RemoveChild(Int32 id, Int32 parentId)
at lambda_method(Closure , ControllerBase , Object[] )
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass37.<>c__DisplayClass39.<BeginInvokeActionMethodWithFilters>b__33()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49()
InnerException:
Also, not sure if it matters, but I have LazyLoadingEnabled = false and AutoDetectChangesEnabled = false.
DbContext.Database.ExecuteSqlCommand(), so I'll probably just stick with that. It just seems like it doesn't quite fit the methodology, but beats spending another day on this small issue. - Josh Jay