0

MVC 응용 프로그램에서 DAL 용 리포지토리 패턴을 사용하고 있습니다.레코드를 업데이트하는 동안 저장소 패턴이 예외가 발생합니다.

이제 엔티티 레코드를 하나 선택하고 엔티티 필드 값을 업데이트하고 업데이트 작업을 수행 할 때 오류가 발생합니다.

동일한 유형의 다른 엔터티 이 이미 동일한 기본 키 값을 가지고 있기 때문에 'DAL.User'유형의 엔터티를 연결하지 못했습니다. '첨부'방법을 사용하거나 엔티티의 상태를 '변경되지 않음'또는 '수정 됨'으로 설정할 때 충돌하는 키 값이있는 경우 이 발생합니다. 이는 일부 엔티티가 새롭고 이 아직 데이터베이스 생성 키 값을 수신하지 않았기 때문일 수 있습니다. 이 경우 'Add'메소드 또는 'Added'엔티티 상태를 사용하여 그래프를 추적하고 이 아닌 새 엔티티의 상태를 '변경되지 않음'또는 'Modified'로 설정하십시오. "} System.Exception

탈취 층 라이브러리에서 : 관리자 클래스 :

private readonly IUnitOfWork _unitOfWork; 
    private IRepository <User , int> UserRepository 
    { 
     get 
     { 
      return _unitOfWork.GetRepository<AccountUser, int>(); 
     } 
    } 
    public void UpdateUserEntity(UserDTO u) 
    { 
     try 
     { 

      User model = new User(); 
      UserRepository.Update(Mapper.Map(u, model)); 
      _unitOfWork.SaveChanges(); 
     } 
     catch (Exception ex) 
     { 
      throw; 
     } 
    } 
다음과 같이 호출

public void Update(TEntity entity) 
{ 
    if (_context.Entry(entity).State != EntityState.Modified) 
    { 
     _dbSet.Attach(entity); 
     _context.Entry(entity).State = EntityState.Modified; 
    } 
} 

: 아래

는 저장소 물건

위의 오류를 해결할 수있는 방법을 안내해주세요.

+0

어디에서 오는 Update() 메소드의 Tentity 인수는 어디에 있습니까? 데이터베이스에서 읽고 수정 한 객체가 데이터베이스에 다시 저장하려고합니까? 또는 애플리케이션의 일부 웹 엔드 포인트에 데이터를 게시하여 생성 된 모델 객체입니까? –

+0

관리자 레이어 항목에 대한 udated 질문을 찾으십시오. – user3711357

+0

[ASP.NET MVC - 같은 유형의 다른 엔터티가 이미 기본 키 값이 같기 때문에 'MODELNAME'유형의 엔터티를 연결하지 못했습니다.] (http://stackoverflow.com/questions/23201907/asp-net-mvc-attached-an-type-of-model-name-failed-another-ent/39557606 # 39557606)을 사용하는 것이 좋습니다. –

답변

0

이유는 다음과 같습니다. "이미 존재하는 개체 대신 새 개체로 TEntity 엔터티". 의미, Entity 프레임 워크는 각 새 개체를 새 항목으로 처리합니다 (기존의 이전 데이터와 동일한 이벤트, PK & 모두). 솔루션은

,

먼저 데이터베이스에서 개체를 검색

마/수정으로

가 그런 상태를 수행 (바람직 기본 키를 변경하지 않고) 동일한 개체에 대한 변경 사항을 할당 업데이트 , SaveChange()

+0

이미 거기에 내가 처음으로 검색 한 다음 ui에 채우고 ui는 값을 업데이트 한 다음 expceiton을 초과하는 update 메서드를 호출합니다. 업데이트 된 항목을 관리하는 레이어 항목을 확인하십시오. – user3711357

3

예외적으로 첨부 된 동일한 키가있는 다른 엔터티가 있지만, 참조.

  • 예외는 이전에 첨부 된 엔터티 때문일 수 있습니다.

    db.Set<Entity>().Attach(new Entity { Id = 123 }); 
    db.Set<Entity>().Attach(new Entity { Id = 123 }); // different reference but same key 
    
  • 또는 자동으로 첨부 된 추적 엔티티로 인해 발생할 수도 있습니다.

    db.Set<Entity>().FirstOrDefault(e => e.Id == 123); // automatically attached 
    db.Set<Entity>().Attach(new Entity { Id = 123 }); // different reference but same key 
    

번째 원인은 항목을 검색 할 때 AsNoTracking 언급함으로써 해결 될 수있다.

db.Set<Entity>().AsNoTracking().FirstOrDefault(e => e.Id == 123); 

또는이 확장 프로그램을 사용하여 첨부 된 항목을 항상 분리 할 수 ​​있습니다.

public static class DbSetExtension 
{ 
    public static void SafeAttach<T>(
     this DbContext context, 
     T entity, 
     Func<T, object> keyFn) where T : class 
    { 
     var existing = context.Set<T>().Local 
      .FirstOrDefault(x => Equals(keyFn(x), keyFn(entity))); 
     if (existing != null) 
      context.Entry(existing).State = EntityState.Detached; 

     context.Set<T>().Attach(entity); 
    } 
} 

사용법.

db.SafeAttach(entity, e => e.Id); 
+0

SafeAttach는 내가 찾고있는 것이 었습니다 - 감사합니다! –

+0

기존 엔티티의 상태가 detached로 변경 되었더라도 새로운 엔티티의 상태가 여전히 오류를 던지더라도 주석을 달았습니까? – ocanal

관련 문제