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";
}
In my case, I was using the ASP.NET Identity Framework. I had used the built in
UserManager.FindByNameAsync
method to retrieve anApplicationUser
entity. I then tried to reference this entity on a newly created entity on a differentDbContext
. This resulted in the exception you originally saw.I solved this by creating a new
ApplicationUser
entity with only theId
from theUserManager
method and referencing that new entity.In this case, it turns out the error is very clear: Entity Framework cannot track an entity using multiple instances of
IEntityChangeTracker
or typically, multiple instances ofDbContext
. The solutions are: use one instance ofDbContext
; access all needed entities through a single repository (depending on one instance ofDbContext
); or turning off tracking for all entities accessed via a repository other than the one throwing this particular exception.When following an inversion of control pattern in .Net Core Web API, I frequently find that I have controllers with dependencies such as:
and usage like
Since all three repositories depend on different
DbContext
instances per request, I have two options to avoid the problem and maintain separate repositories: change the injection of the DbContext to create a new instance only once per call:or, if the child entity is being used in a read-only manner, turning off tracking on that instance:
Alternatively to injection and even worse Singleton, you can call Detach method before Add.
EntityFramework 6:
((IObjectContextAdapter)cs).ObjectContext.Detach(city1);
EntityFramework 4:
cs.Detach(city1);
There is yet another way, in case you don't need first DBContext object. Just wrap it with using keyword:
Steps to reproduce can be simplified to this:
Code without error:
I had the same problem and I could solve making a new instance of the object that I was trying to Update. Then I passed that object to my reposotory.
Use the same DBContext object throughout the transaction.