Reputation: 196
I have the following code for editing the departments a user is in. For some reason, method1
causes EF to try and insert the relationship again (and causing a primary key error), where method2
succeeds.
Why does the code of method1
not know that by reassigning the value, I only want the new collection of departments? Is method2
the preferred method to update values? I haven't had to do it this way with one to many relationships.
public class User
{
public string name { get; set; }
public virtual List<Department> Departments { get; set; }
}
public class Department
{
public string name { get; set; }
public virtual List<User> Users { get; set; }
}
public void Method1(list<Department> departments, string userId)
{
var user = DbContext.Users.FirstOrDefault(u=> u.Id == userId);
user.departments = departments;
db.SaveChanges()
}
public void Method2(list<Department> departments, string userId)
{
var user = DbContext.Users.FirstOrDefault(u=> u.Id == userId);
user.departments.clear();
user.departments = departments;
db.SaveChanges()
}
Upvotes: 2
Views: 704
Reputation: 13498
Below on departments, I will mean Users2Departments
table.
Probably, it happened because, when you wrote user.departments.clear();
you loaded all related departments(via LazyLoading
), so they become trackable by EF
and were successfully marked as Deleted
(after clear()
call). And then new departments were assigned to user
, i.e. marked as Added
. All is correct.
But, if you just perform only assigning: user.departments = departments
, EF
will not know or not care, that there are existed departments and it should delete them, because, at least, they are not tracked, because they not loaded, since user.departments
literal is located at LeftHandSide(user.departments.clear()
is RightHandSide). Moreover Users2Departments
table is implicit table. So EF
only inserts new departments without deletion of previous ones, so exception will may occur.
Upvotes: 2