2013-03-21 3 views
2

두 개의 관련 테이블, 즉 ObjectState으로 구성된보기 ObjectDisplay이 있습니다. StateObject의 상태를 나타내고,보기는 각 Object에 대해 가장 최근의 State의 일부 세부 사항을 가져옵니다.뷰는 기본 테이블의 데이터 변경 사항을 즉시 반영합니까?

이 정보를 표시하는 페이지에서 사용자는 몇 가지 설명을 입력하여 새로운 State을 생성 할 수 있습니다. 새로운 State을 만든 후 즉시 ObjectObjectDisplay에서 가져 와서 다시 보내서 부분보기로 삭제하고 페이지의 눈금에서 Object을 바꿉니다.

// Add new State. 
db.States.Add(new State() 
{ 
    ObjectId = objectId, 
    Comments = comments, 
    UserName = username 
}); 

// Save the changes (executes all of the above). 
db.SaveChanges(); 

// Return the new Object information. 
return db.Objects.Single(c => c.ObjectId == objectId); 

내 DB 추적에 따르면, Single 호출은 SaveChanges 호출 후 약 70 밀리 발생하고 동일한 SPID에서 발생합니다.

문제의 현재 : 데이터베이스의 기본값은 RecordDate입니다. State에서 GETUTCDATE()으로 - 나는 스스로 날짜를 제공하지 않습니다. 내가보고있는 것은 이 State의 이전 State이고 의 Comments이 이전 State 인 의 RecordDate이 반환된다는 것입니다. 나는 Object이 (가) 이전 State 님의 정보를 가지고있는 것을보고 있습니다. 페이지를 새로 고치면 모든 올바른 정보가 있지만 데이터베이스/EF의 초기 호출에서 잘못된 정보가 반환됩니다.

그래서 ... 무엇이 잘못되었을 수 있습니까? 보기가 충분히 빠르게 업데이트되지 않을 수 있습니까? EF에서 뭔가 진행될 수 있습니까? 나는 어디에서부터 시작해야할지 정말로 모른다.

+0

? 데이터를 변경하는 쿼리와 다른 세션에서 뷰가 호출되고 있습니까? – Oded

+0

@Oded : 추적에서 '감사 로그인'줄에는 '트랜잭션 격리 수준 설정 완료'가 있습니다. 둘 다 동일한 SPID에서 수행됩니다. – zimdanen

답변

1

이전에 동일한 Object 엔티티를 DbContext에로드 한 경우 EF는 캐시 된 인스턴스를 부실 값으로 반환하고 SQL에서 반환 된 값을 무시합니다.

가장 간단한 해결책은 그것을 반환하기 전에 개체를 다시로드하는 것입니다 : 쿼리가 실행되는 어떤 격리 수준

var result = db.Objects.Single(c => c.ObjectId == objectId); 
db.Entry(result).Reload(); 
return result; 
+1

그건 내 첫 번째 생각 이었지만 OP는 프로파일 러에서 실행되는 쿼리를 봅니다. 캐시 된 값이 사용되면 쿼리가 전혀 실행되지 않아야합니다. –

+0

'Reload'가 작동하고, 같은'DbContext'에서'Object'를 먼저로드합니다. 나는 왜 그것이 데이터베이스로 가고 그 다음에 결과를 무시하고 캐싱 된 값을 사용하는지 의아하게 생각한다. 실제로 그것이 정확하게 일어나고 있기 때문이다. (심지어 Single 대신에 'First'로 바꾸더라도). 가장 좋은 방법은'DbContext'에서 앞서 가져온 원래의'Object'를'Reload'하는 것입니다. 고마워! – zimdanen

+0

@SebastianMeine : 불행히도 쿼리는 계속 실행되지만 EF는 결과를 버리게됩니다. –

0

이것은 실제로 이상합니다. SQL Server에서 뷰는 기본적으로 유지되지 않으므로 기본 데이터의 변경 내용이 즉시 표시됩니다. 쿼리를 효과적으로 유지하면서 뷰에 클러스터 된 인덱스를 만들 수 있지만이 경우 데이터가 동 기적으로 업데이트되므로 변경 내용을 즉시 확인해야합니다.

스냅 숏 격리 수준으로 작업하는 경우 변경 내용이 다른 SPID에 즉시 표시되지 않을 수 있지만 동일한 SPID를 사용하고 스냅 숏 격리를 사용하지 않아도 마찬가지입니다.

이 시점에서 남은 것은 응용 프로그램 계층뿐입니다. 실제로 호출 스택에서 단일 호출의 결과를 사용하고 있습니까? 그렇지 않으면 어딘가에 손실됩니다. 페이지의 새로 고침이 다른 코드 경로를 사용한다고 가정합니다. 그러면 왜 코드가 작동하는지 설명 할 수 있습니다.

+0

결과를 사용하여 호출하는 웹 응용 프로그램의 데이터 그리드 내에서 행을 업데이트합니다. 새로 고침은 실제로 다른 코드 경로를 사용합니다 (다른 서비스 작업을 통해 전체 표를로드합니다). – zimdanen

관련 문제