This is the way how EF works if you incorrectly use detached entities. I suppose you are using something like this:
var employee = new Employee();
employee.Department = GetDepartmentFromSomewhere(departmentId);
...
using (var context = new YourContext())
{
context.Employees.AddObject(employee);
context.SaveChanges();
}
This code prepared employee entity, added reference to existing department and saved new employee to the database. Where is the problem? The problem is that AddObject
doesn't add only employee but whole object graph. That is how EF works - you cannot have object graph where part of objects are connected to context and part of not. AddObject
adds every object in the graph as a new one (new one = insert in database). So you must either change sequence of your operations or fix state of entities manually so that your context knows that department already exists.
First solution - use the same context for loading department and saving employee:
using (var context = new YourContext())
{
var employee = new Employee();
...
context.Employees.AddObject(employee);
employee.Department = context.Departments.Single(d => d.Id == departmentId);
context.SaveChanges();
}
Second solution - connect entities to the context separately and after that make reference between entities:
var employee = new Employee();
...
var department = GetDepartmentFromSomewhere(departmentId);
using (var context = new YourContext())
{
context.Employees.AddObject(employee);
context.Departments.Attach(department);
employee.Department = department;
context.SaveChanges();
}
Third solution - correct state of the department manually so that context doesn't insert it again:
var employee = new Employee();
employee.Department = GetDepartmentFromSomewhere(departmentId);
...
using (var context = new YourContext())
{
context.Employees.AddObject(employee);
context.ObjectStateManager.ChangeObjectState(employee.Department,
EntityState.Unchanged);
context.SaveChanges();
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…