entity object cannot be referenced by multiple instances of IEntityChangeTracker. while adding related objects to entity in Entity Framework 4.1
Because these two lines ...
EmployeeService es = new EmployeeService();
CityService cs = new CityService();
... don't take a parameter in the constructor, I guess that you create a context within the classes. When you load the city1
...
Payroll.Entities.City city1 = cs.SelectCity(...);
...you attach the city1
to the context in CityService
. Later you add a city1
as a reference to the new Employee
e1
and add e1
including this reference to city1
to the context in EmployeeService
. As a result you have city1
attached to two different context which is what the exception complains about.
You can fix this by creating a context outside of the service classes and injecting and using it in both services:
EmployeeService es = new EmployeeService(context);
CityService cs = new CityService(context); // same context instance
Your service classes look a bit like repositories which are responsible for only a single entity type. In such a case you will always have trouble as soon as relationships between entities are involved when you use separate contexts for the services.
You can also create a single service which is responsible for a set of closely related entities, like an EmployeeCityService
(which has a single context) and delegate the whole operation in your Button1_Click
method to a method of this service.
Steps to reproduce can be simplified to this:
var contextOne = new EntityContext();
var contextTwo = new EntityContext();
var user = contextOne.Users.FirstOrDefault();
var group = new Group();
group.User = user;
contextTwo.Groups.Add(group);
contextTwo.SaveChanges();
Code without error:
var context = new EntityContext();
var user = context.Users.FirstOrDefault();
var group = new Group();
group.User = user; // Be careful when you set entity properties.
// Be sure that all objects came from the same context
context.Groups.Add(group);
context.SaveChanges();
Using only one EntityContext
can solve this. Refer to other answers for other solutions.
This is an old thread, but another solution, which I prefer, is just update the cityId and not assign the hole model City to Employee... to do that Employee should look like:
public class Employee{
...
public int? CityId; //The ? is for allow City nullable
public virtual City City;
}
Then it's enough assigning:
e1.CityId=city1.ID;