2012-06-25 6 views
1

단일 데이터 컨텍스트 (한 번 생성됨)가 있고 동일한 데이터베이스 레코드를 여러 번 가져 오는 데 사용합니다. 예를 들어 동일한 제품 레코드를 가져 오는 동일한 제품 레코드를 가져옵니다.EF는 매번 데이터베이스에 쿼리합니다.

내가 호출 할 때마다 context.Products.Single(p => p.ProdID == 1) 컨텍스트는 제품 엔터티의 동일한 인스턴스를 반환하지만 SQL Server 프로파일 러에 표시되는 매번 데이터베이스를 쿼리합니다.

호출간에 일부 속성을 수정하여 동일한 인스턴스를 반환하는지 확인합니다. 다음 호출은 수정 된 특성이있는 인스턴스를 리턴합니다.

매번 데이터베이스를 쿼리하는 이유와이를 피할 수있는 방법이 있습니까?

답변

1

ObjectContext.GetObjectByKey (DbSet<T>.FindDbContext)은 해당 키를 사용하여 엔터티를 쿼리 할 수 ​​있습니다. 이 메소드는, 지정된 키를 가지는 오브젝트가 컨텍스트에 벌써 첨부되고 있는지 어떤지를 체크합니다. 그렇다면 데이터베이스를 조회하지 않고 해당 오브젝트를 리턴합니다. 컨텍스트에 존재하지 않으면 데이터베이스 쿼리를 실행합니다.

LINQ 쿼리는 일반적으로 개체가 컨텍스트에 이미 연결되어 있는지 여부에 관계없이 데이터베이스를 쿼리합니다. EF는 쿼리의 결과를 알지 못하기 때문에 개체가 연결되었는지 여부를 알 수 없습니다. EF 이 쿼리가 필요한지 아닌지를 알 수 있기 때문에 키에 의한 LINQ 쿼리는 이론적으로 예외입니다. 해당 키가있는 개체가 이미 첨부되어 있는지 확인할 수 있기 때문입니다. 그러나이 예외는 처리되지 않으므로 GetObjectByKey이 존재하며 다른 모든 LINQ 쿼리와 마찬가지로 데이터베이스를 쿼리합니다.

쿼리 결과는 ObjectSet의 MergeOption에 의해 결정됩니다. 기본값은 AppendOnly입니다. 즉, 키가있는 오브젝트가 이미 컨텍스트에 첨부되어 있으면 쿼리 결과가 버려집니다. 아무 것도 쿼리에 의해 덮어 쓰이거나 새로 고침되지 않습니다. 키가있는 객체가 컨텍스트에 존재하지 않는 경우에만 질의 결과의 객체가 구체화되고 컨텍스트에 연결됩니다. MergeOption을 선택하여이 기본 동작을 변경할 수 있습니다.

+0

위대한 설명, 고마워요. –

2

다른 사용자가 첫 번째 호출과 두 번째 호출 사이에서 레코드를 수정했을 수 있기 때문에이 작업이 수행됩니다.

데이터가 비교적 정적 인 경우 caching solution을 고려하십시오.

+0

다른 사용자가 내 통화간에 레코드를 수정하면 컨텍스트가 변경 사항을 던지고 다른 사용자가 수정 한 데이터를 다시로드한다는 의미입니까? –

+0

사용중인 동시성 모델에 따라 다릅니다. 일반적으로 말하지만, 마지막 편집이 승리하지만, 편집을 시도 할 때 다른 사용자가 기록을 잠근 경우 해당 편집이 이길 수 있습니다. –

관련 문제