I have an ASP.NET WebForms project with N-Layers using Entity Framework 5.
I have two entities: Cliente and Banda.
One Cliente may have many Banda’s, and one Banda may have many Cliente’s
In the bussines layer I have this code:
public void Update(Cliente cliente)
{
using (MegaStudioEntities contexto = new MegaStudioEntities())
{
if (contexto.Entry(cliente).State == EntityState.Detached)
contexto.Entry(cliente).State = EntityState.Modified;
//Delete existing relations
var qBandas = from qb in contexto.Bandas.Where(b => b.Clientes.Any(c => c.IdCliente == cliente.IdCliente))
select qb;
foreach (Banda b in qBandas.ToList())
((IObjectContextAdapter)contexto).ObjectContext.ObjectStateManager.ChangeRelationshipState(cliente, b, c => c.Bandas, EntityState.Deleted);
contexto.SaveChanges();
//Adding new relations
foreach (Banda banda in cliente.Bandas)
{
contexto.Bandas.Attach(banda);
((IObjectContextAdapter)contexto).ObjectContext.ObjectStateManager.ChangeRelationshipState(cliente, banda, c => c.Bandas, EntityState.Added);
}
cliente.TipoCliente = contexto.TipoClientes.Find(cliente.IdTipoCliente);
cliente.FechaModificacion = System.DateTime.Now;
Encriptar(cliente);
contexto.SaveChanges();
}
}
The first time I call Update method, run sucessfully, but the second time I get this error:
“An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.”
What I forget to close?
This is the correct way to update many to many relations in EF5?
Thanks in advance!!!
Martin
UPDATE 1:
Finally my code is like that:
public void Update(Cliente cliente)
{
using (MegaStudioEntities contexto = new MegaStudioEntities())
{
Cliente savedClient = contexto.Clientes.Find(cliente.IdCliente);
foreach (var banda in savedClient.Bandas.ToList())
{
savedClient.Bandas.Remove(contexto.Bandas.Find(banda.IdBanda));
}
foreach (var banda in cliente.Bandas)
{
savedClient.Bandas.Add(contexto.Bandas.Find(banda.IdBanda));
}
contexto.Entry(savedClient).CurrentValues.SetValues(cliente);
contexto.SaveChanges();
}
}
Thanks Gert Arnold!!!
You don’t really have to attach any object to the context. So you can prevent this exception by not doing that.
I’m not sure if this break code in
Encriptar(cliente);because (obviously) I don’t know what happens there.As you see, you add and remove associations in a m:m relationship by adding/removing objects. You hardly ever (probably never) need to manipulate relationship state explicitly. If you feel a need to do that it most likely indicates that you overlook an easier way to achieve what you want.