2012-12-04 2 views
4

Entity Framework 5를 사용하여 N-Layer를 사용하는 ASP.NET WebForms 프로젝트가 있습니다. Cliente와 Banda의 두 엔티티가 있습니다. 한 Cliente 많은 반다의 가질 수 있으며, 하나의 반다 많은 Cliente 년대 탈취 층에서EF5에서 many to many 관계를 업데이트 할 때 오류가 발생했습니다

이 코드가있을 수 있습니다

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(); 
     } 
    } 

내가 Update 메서드를 호출 처음으로, 성공적으로 실행되지만 두 번째

"동일한 키를 가진 객체가 ObjectStateManager에 이미 존재하며 ObjectStateManager는 동일한 키를 가진 여러 객체를 추적 할 수 없습니다."

내가 닫을 것을 잊었을 때? 이것은 EF5에서 많은 관계를 많은 관계로 업데이트하는 올바른 방법입니까?

미리 감사드립니다.

마틴

UPDATE 1 :

마지막으로 내 코드가 같다 :

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(); 
      } 
     } 

감사 거트 아놀드!

+0

오류가 발생하는 줄은 무엇입니까? –

+0

wery 중요한 줄'savedClient.Bandas.Remove (contexto.Bandas.Find (banda.IdBanda))' – Kuncevic

답변

4

실제로 컨텍스트에 개체를 연결할 필요는 없습니다. 그래서 그렇게하지 않으면이 예외를 막을 수 있습니다.

public void Update(Cliente cliente) 
{ 
    using (MegaStudioEntities contexto = new MegaStudioEntities()) 
    { 
     Cliente savedClient = contexto.TipoClientes.Find(cliente.IdCliente); 

     foreach (var banda in savedClient.Bandas.ToList()) 
     { 
      savedClient.Bandas.Remove(banda); 
     } 
     foreach (var banda in cliente.Bandas) 
     { 
      savedClient.Bandas.Add(banda); 
     } 

     savedClient.IdTipoCliente = cliente.IdTipoCliente; 
     savedClient.FechaModificacion = System.DateTime.Now; 

     Encriptar(cliente); 
     contexto.SaveChanges(); 
    } 
} 

나는 Encriptar(cliente);이 휴식 코드가 있기 때문에 (분명히) 내가 거기에 어떻게되는지 모르는 경우에 확실하지 않다.

위에서 보셨 듯이 개체를 추가/제거하여 m : m 관계의 연결을 추가 및 제거 할 수 있습니다. 관계 상태를 명시 적으로 조작 할 필요가 거의 없습니다. 그렇게해야 할 필요성이 느껴진다면 가장 쉽게 원하는 것을 성취 할 수있는 간과가 있음을 나타낼 수 있습니다.

+0

안녕하세요, aswer에 감사드립니다! 나머지 클라이언트의 특성에 대해서는 어떻게해야합니까? "savedClient.Name = cliente.Name;"? – mneu

+0

변경된 경우에만. 기본적으로 UI에서 변경할 수있는 속성을 복사해야합니다. –

+0

코드에서 변경할 필요가있는 것은 banda가 컨텍스트에 연결되어 있지 않기 때문에 "savedClient.Bandas.Remove (contexto.Bandas.Find (banda.IdBanda));"와 같은 줄에 있습니다. 솔루션에 감사드립니다!, 내가 싫어할 수있는 유일한 것은 수동으로 모든 속성을 할당하는 것입니다. 감사! – mneu