2013-08-18 2 views
1

저는 매우 이상한 행동 양식 엔티티 프레임 워크를 얻었습니다. WebApi 응용 프로그램을 코딩 중이므로 브라우저에서 가져온 개체가 연결이 끊어 지거나 분리됩니다. 내가 가져온 데이터는 트랜잭션 적으로 데이터베이스의 테이블과 일치하지 않습니다. 데이터베이스에서 수행 할 실제 업데이트를 얻으려면 여러 가지 조회 및 데이터 조작을해야합니다.Entity Framework에서 부실 캐시를 처리하는 방법은 무엇입니까?

내가 가진 것처럼 보이는 문제는 데이터를 쿼리 할 때 추적 변경 캐시를 채우는 것입니다. 데이터의 진정한 출처는 데이터베이스 여야하기 때문에 저에게는 문제가되지 않습니다. 마지막으로 데이터를 변경하고 SaveChanges를 호출하면 제약 조건 오류가 발생합니다. 여기에 내 발걸음이있다.

  1. 데이터를 쿼리하십시오.
  2. 삽입 할 행을 만듭니다.
  3. 행을 db와 비교하여 db를 변경합니다.

는 Ctx.ChangeTracker.Entries의 데이터()를 검토 한 I 수정으로 삭제 될 예정 때 항목이 표시된 삭제되는 것을 발견했다. 내가 작업 한 방식은 3 단계에서 새로운 컨텍스트를 만드는 것입니다. 그리고 마술처럼 작동하기 시작했습니다. 그게 다라고 생각했지만 테스트 케이스에서는 데이터베이스에서 마지막으로 읽은 것만으로도 트랜잭션이 올바르게 작성되었는지 확인할 수 있습니다. 그리고 나는 이미 지워질 여분의 행을 얻고있었습니다. 사실 db를 직접 확인했을 때였습니다. 마지막으로 다시 읽으려는 새로운 상황이 문제를 해결했습니다.

나는 단지 기본 캐시 설정이 변경 사항을 추적하고 쿼리의 속도를 높이는 데 사용되지 않는다고 가정했습니다.

내 쿼리에서 AsNoTracking을 사용하려고하면 오류가 발생하는 것처럼 쿼리 된 행을 삭제하려고하면 문제가 발생합니다. 그리고 내 코드에서 나중에까지 삭제 또는 수정할지 여부를 알지 못합니다. 새 컨텍스트를 만들 필요가 없도록 캐시를 지울 수있는 방법이 있습니까?

이러한 문제를 해결할 더 좋은 방법이 있습니까?

편집 :

AsNoTracking은 어느 정도 트릭을 할 것입니다. 오류를 방지하기 위해 더 많은 DbContext 복사본을 인스턴스화하는 자신을 발견했습니다. 여러 엔티티를 순서대로 삭제해야하거나 널 (NULL) 외부 키 오류가 트리거됩니다.

var details = oldInvoice.details.ToList(); 

Context.Entry(oldInvoice).State = EntityState.Unchanged; 
Context.Entry(oldInvoice).State = EntityState.Deleted; 
details.ForEach(a => Context.Entry(a).State = EntityState.Deleted); 
+0

오랜 시간 동안 트래킹 그래프가 제대로 작동하지 않을 때 컨텍스트를 유지하는 것은 좋지 않습니다. 내 추천은 요청 사이에 컨텍스트를 다시 사용하지 않는 것입니다. 이것은 또한 동시 업데이트 문제를 해결해야합니다. –

답변

1

엔티티 프레임 워크는 SaveChanges()에 통화에 잡을 수있는 예외 DbUpdateConcurrencyException을 제공합니다.

catch (DbUpdateConcurrencyException ex) 
    { 
     saveFailed = true; 

     // Get the current entity values and the values in the database 
     var entry = ex.Entries.Single(); 
     var currentValues = entry.CurrentValues; 
     var databaseValues = entry.GetDatabaseValues(); 

     // Choose an initial set of resolved values. In this case we 
     // make the default be the values currently in the database. 
     var resolvedValues = databaseValues.Clone(); 

     // Have the user choose what the resolved values should be 
     HaveUserResolveConcurrency(currentValues, databaseValues, 
            resolvedValues); 

     // Update the original values with the database values and 
     // the current values with whatever the user choose. 
     entry.OriginalValues.SetValues(databaseValues); 
     entry.CurrentValues.SetValues(resolvedValues); 
    } 

} while (saveFailed); 

또한, 귀하의 업데이트 코드뿐만 아니라 의심스러운 소리 :이 같은 오류가 뭔가를 통해 루프 수 있습니다. 일반적으로 WebApi 또는 다른 메커니즘을 통해 클라이언트에 데이터를 전달할 때 반환되는 데이터에는 추적 데이터가 없기 때문에 존재하는지 확인하고 컨텍스트에 다시 첨부하고 상태를 변경해야합니다 만약 SaveChanges()로 전화하기 전에 EntityState.Modified으로 전화하십시오.

+0

Andrew가 대답 해 주셔서 감사합니다. 누락 된 추적 데이터에 대해 정확합니다. 그래서 저는 여러분이 말한 것과 정확히 같습니다. 이전 쿼리가 추적 데이터를 엉망으로 만든다는 점을 제외하면 –

관련 문제