Estoy tratando de guardar los detalles del empleado, que tiene referencias con la ciudad. Pero cada vez que intento guardar mi contacto, que está validado, aparece la excepción "ADO.Net Entity Framework. Un objeto de entidad no puede ser referenciado por múltiples instancias de IEntityChangeTracker"
Había leído muchas publicaciones pero aún no tenía la idea exacta de qué hacer ... mi código de clic del botón Guardar se muestra a continuación
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);
}
y código de servicio del empleado
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";
}
fuente
Form
(lo que sea, solo representa una unidad de trabajo) porThread
(porqueDbContext
no se garantiza que sea seguro para subprocesos).Los pasos para reproducir se pueden simplificar a esto:
Código sin error:
Usando solo uno
EntityContext
puede resolver esto. Consulte otras respuestas para otras soluciones.fuente
Este es un hilo antiguo, pero otra solución, que prefiero, es simplemente actualizar cityId y no asignar el modelo de agujero City a Employee ... para hacer eso, Employee debería verse así:
Entonces es suficiente asignar:
fuente
Alternativamente a la inyección y, lo que es peor, a Singleton, puede llamar al método Separar antes de Agregar.
EntityFramework 6:
((IObjectContextAdapter)cs).ObjectContext.Detach(city1);
EntityFramework 4:
cs.Detach(city1);
Hay otra forma, en caso de que no necesite el primer objeto DBContext. Simplemente envuélvelo usando la palabra clave:
fuente
dbContext1.Entry(backgroundReport).State = System.Data.Entity.EntityState.Detached
'para separar y luego pude usardbContext2.Entry(backgroundReport).State = System.Data.Entity.EntityState.Modified;
para actualizar. Trabajó como un sueñoTuve el mismo problema, pero mi problema con la solución de @ Slauma (aunque excelente en algunos casos) es que recomienda pasar el contexto al servicio, lo que implica que el contexto está disponible desde mi controlador. También fuerza un fuerte acoplamiento entre mi controlador y las capas de servicio.
Estoy usando Dependency Injection para inyectar las capas de servicio / repositorio en el controlador y, como tal, no tengo acceso al contexto desde el controlador.
Mi solución fue hacer que las capas de servicio / repositorio usaran la misma instancia del contexto: Singleton.
Contexto Singleton Class:
Referencia: http://msdn.microsoft.com/en-us/library/ff650316.aspx
y http://csharpindepth.com/Articles/General/Singleton.aspx
Clase de repositorio:
Existen otras soluciones, como instanciar el contexto una vez y pasarlo a los constructores de sus capas de servicio / repositorio u otro que leí sobre el que está implementando el patrón de Unidad de trabajo. Estoy seguro de que hay más ...
fuente
En mi caso, estaba usando ASP.NET Identity Framework. Había usado el
UserManager.FindByNameAsync
método incorporado para recuperar unaApplicationUser
entidad. Luego intenté hacer referencia a esta entidad en una entidad recién creada en una diferenteDbContext
. Esto resultó en la excepción que viste originalmente.Resolví esto creando una nueva
ApplicationUser
entidad con soloId
elUserManager
método y haciendo referencia a esa nueva entidad.fuente
Tuve el mismo problema y pude resolver haciendo una nueva instancia del objeto que estaba tratando de actualizar. Luego pasé ese objeto a mi repositorio.
fuente
En este caso, resulta que el error es muy claro: Entity Framework no puede rastrear una entidad utilizando múltiples instancias
IEntityChangeTracker
o, por lo general, múltiples instancias deDbContext
. Las soluciones son: use una instancia deDbContext
; acceder a todas las entidades necesarias a través de un único repositorio (dependiendo de una instancia deDbContext
); o desactivar el seguimiento para todas las entidades a las que se accede a través de un repositorio que no sea el que arroja esta excepción particular.Cuando sigo una inversión del patrón de control en .Net Core Web API, con frecuencia encuentro que tengo controladores con dependencias como:
y uso como
Dado que los tres repositorios dependen de diferentes
DbContext
instancias por solicitud, tengo dos opciones para evitar el problema y mantener repositorios separados: cambiar la inyección de DbContext para crear una nueva instancia solo una vez por llamada:o, si la entidad secundaria se usa de manera de solo lectura, desactivando el seguimiento en esa instancia:
fuente
Use el mismo objeto DBContext en toda la transacción.
fuente
Llegué a este mismo problema después de implementar IoC para un proyecto (ASP.Net MVC EF6.2).
Por lo general, inicializaría un contexto de datos en el constructor de un controlador y usaría el mismo contexto para inicializar todos mis repositorios.
Sin embargo, usar IoC para crear instancias de los repositorios hizo que todos tuvieran contextos separados y comencé a recibir este error.
Por ahora he vuelto a actualizar los repositorios con un contexto común mientras pienso en una mejor manera.
fuente
Así es como me encontré con este problema. Primero necesito guardar mi
Order
que necesita una referencia a miApplicationUser
tabla:El problema es que estoy inicializando un nuevo ApplicationDbContext para guardar mi nueva
Order
entidad:Entonces, para resolver el problema, utilicé el mismo ApplicationDbContext en lugar de usar el UserManager incorporado de ASP.NET MVC.
En lugar de esto:
Usé mi instancia actual de ApplicationDbContext:
fuente
Fuente de error:
Espero que alguien ahorre un tiempo precioso
fuente