Search code examples
c#asp.netentity-frameworkado.netforeign-keys

entity object cannot be referenced by multiple instances of IEntityChangeTracker. while adding related objects to entity in Entity Framework 4.1


I am trying to save Employee details, which has references with City. But everytime I try to save my contact, which is validated I get the exception "ADO.Net Entity Framework An entity object cannot be referenced by multiple instances of IEntityChangeTracker"

I had read so many post but still not getting the exact idea of what to do... my Save button click code is given below

protected void Button1_Click(object sender, EventArgs e)
    {
        EmployeeService es = new EmployeeService();
        CityService cs = new CityService();

        DateTime dt = new DateTime(2008, 12, 12);
        Payroll.Entities.Employee e1 = new Payroll.Entities.Employee();

        Payroll.Entities.City city1 = cs.SelectCity(Convert.ToInt64(cmbCity.SelectedItem.Value));

        e1.Name = "Archana";
        e1.Title = "aaaa";
        e1.BirthDate = dt;
        e1.Gender = "F";
        e1.HireDate = dt;
        e1.MaritalStatus = "M";
        e1.City = city1;        

        es.AddEmpoyee(e1,city1);
    }

and Employeeservice Code

public string AddEmpoyee(Payroll.Entities.Employee e1, Payroll.Entities.City c1)
        {
            Payroll_DAO1 payrollDAO = new Payroll_DAO1();
            payrollDAO.AddToEmployee(e1);  //Here I am getting Error..
            payrollDAO.SaveChanges();
            return "SUCCESS";
        }

Solution

  • 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.