I am creating a building mapping application with my data stored in a SQL Server Express database and am running into trouble saving related entities when I change the parent ID within the child object.
In simple terms, I have a 'Wall' class and a 'Door' class, where each Door belongs to a Wall as follows.
public class Wall() {
public int ID { get; set; }
public virtual ICollection<Door> Doors { get; set; }
}
public class Door() {
public int ID { get; set; }
public int WallID { get; set; }
public virtual Wall Wall { get; set; }
}
I am trying to move a Door from one Wall to another at runtime (i.e. end user wants to move the door), which I try:
private void MoveDoor()
{
// doorToMove was previously loaded from the context but is detached now while the user makes updates
// user changes location of door:
doorToMove.WallID = wallToMoveTo.ID;
SaveDoor(doorToMove);
}
private void SaveDoor(Door door)
{
using (var db = new BuildingDataContext())
{
db.Entry(door).State = EntityState.Modified;
db.SaveChanges();
}
}
However, when the entity state of the door is changed to EntityState.Modified, I get this error message:
'A referential integrity constraint violation occurred: The property value(s) of 'Wall.ID' on one end of a relationship do not match the property value(s) of 'Door.WallID' on the other end.'
I have tried removing the door from the previous wall's collection of doors and adding it to the new wall's collection of doors but that didn't help. The only way I've gotten it to work is if I query the door from the DB and then update it's WallID, like this:
private void SaveObject(Door door)
{
using (var db = new BuildingDataContext())
{
Door findDoor = db.Doors.Find(door.ID);
findDoor.WallID = door.Wall.ID;
db.Entry(findDoor).State = EntityState.Modified;
db.SaveChanges();
}
}
However, there are other properties of the door that will also change so I don't want to manually update properties one by one between my changed door and the door in the database.
I've looked through a lot of articles/posts and have found some helpful but not enough to solve my problem entirely. This post (Cleanly updating a hierarchy in Entity Framework) seems close to what I need, except I don't want to create new children each time, I simply want to move a child (door) from one parent (wall) to another.
I am relatively new to Entity Framework and still trying to wrap my mind around how it all fits together, any help on this would be greatly appreciated!
UPDATE:
When I remove the door from the previous wall's collection of doors and add it to the new wall's collection of doors, I receive the same error. Here's my code:
private void MoveDoor()
{
// doorToMove was previously loaded from the context but is detached now while the user makes updates
// user changes location of door:
doorToMove.Wall = newWall;
prevWall.Doors.Remove(doorToMove);
newWall.Doors.Add(doorToMove);
// Other properties of door could be edited here (coordinates, width, etc)
SaveDoor(doorToMove, prevWall, newWall);
}
private void SaveDoor(Door door, Wall prevWall, Wall newWall)
{
using (var db = new BuildingDataContext())
{
db.Entry(prevWall).State = EntityState.Modified; // Errors here
db.Entry(newWall).State = EntityState.Modified;
db.Entry(door).State = EntityState.Modified; // I still need to save the door to save other properties that may have been changed
db.SaveChanges();
}
}