[.net] 엔터티 프레임 워크 및 연결 풀링

최근에 .NET 4.0 응용 프로그램에서 Entity Framework 4.0을 사용하기 시작했으며 풀링과 관련하여 몇 가지 궁금합니다.

  1. 내가 아는 연결 풀링은 ADO.NET 데이터 공급자, 내 경우에는 MS SQL 서버의 연결 풀링으로 관리됩니다. 새 엔티티 컨텍스트 ( ObjectContext) 를 인스턴스화 할 때 적용됩니다 ( 예 : 매개 변수 없음 new MyDatabaseModelEntities()?).

  2. a) 응용 프로그램에 대한 전역 엔터티 컨텍스트를 생성하거나 (예 : 하나의 정적 인스턴스) b) 주어진 각 작업 / 방법에 대해 엔터티 컨텍스트를 생성하고 노출하는 using블록 의 장점과 단점은 무엇입니까?

  3. 알아야 할 특정 시나리오에 대한 다른 권장 사항, 모범 사례 또는 일반적인 접근 방법은 무엇입니까?



답변

  1. 연결 풀링은 다른 ADO.NET 응용 프로그램에서와 같이 처리됩니다. 엔티티 연결은 여전히 ​​기존 연결 문자열과 함께 기존 데이터베이스 연결을 사용합니다. 연결 문자열을 사용하지 않으려면 연결 풀링을 끌 수 있다고 생각합니다. ( ADO.NET (SQL Server 연결 풀링) 에 대해 자세히 알아보십시오 )
  2. 절대로 글로벌 컨텍스트를 사용하지 마십시오. ObjectContext는 내부적으로 아이디 맵 및 작업 단위를 포함한 여러 패턴을 구현합니다. 전역 컨텍스트 사용의 영향은 응용 프로그램 유형마다 다릅니다.
  3. 웹 애플리케이션의 경우 요청 당 단일 컨텍스트를 사용하십시오. 웹 서비스의 경우 통화 당 단일 컨텍스트를 사용하십시오. WinForms 또는 WPF 응용 프로그램에서는 양식 또는 발표자마다 단일 컨텍스트를 사용하십시오. 이 접근 방식을 사용할 수없는 특별한 요구 사항이있을 수 있지만 대부분의 상황에서는 이것으로 충분합니다.

WPF / WinForm 응용 프로그램에 대한 단일 개체 컨텍스트의 영향을 알고 싶다면이 문서를 확인 하십시오 . NHibernate Session에 관한 것이지만 아이디어는 동일합니다.

편집하다:

EF를 사용하면 기본적으로 각 엔티티가 컨텍스트 당 한 번만로드됩니다. 첫 번째 쿼리는 엔터티 인스턴스를 생성하고 내부에 저장합니다. 동일한 키를 가진 엔터티가 필요한 후속 쿼리는이 저장된 인스턴스를 반환합니다. 데이터 저장소의 값이 변경 되어도 초기 쿼리의 값이있는 엔터티를 계속받습니다. 이것을 신원 맵 패턴 이라고 합니다. 개체 컨텍스트를 강제로 개체를 다시로드 할 수 있지만 단일 공유 인스턴스를 다시로드 할 수 있습니다.

SaveChanges컨텍스트 를 호출 할 때까지 엔터티에 대한 변경 내용이 유지되지 않습니다 . 여러 엔터티에서 변경을 수행하고 한 번에 저장할 수 있습니다. 이것을 작업 단위 패턴 이라고 합니다. 저장할 수정 된 첨부 된 엔티티를 선택적으로 말할 수 없습니다.

이 두 패턴을 결합하면 흥미로운 효과가 나타납니다. 전체 애플리케이션에 대해 하나의 엔티티 인스턴스 만 있습니다. 변경 사항이 아직 지속되지 않거나 커밋되지 않은 경우에도 엔터티에 대한 변경 내용은 전체 응용 프로그램에 영향을줍니다. 대부분의 경우 이것은 원하는 것이 아닙니다. WPF 응용 프로그램에 편집 양식이 있다고 가정하십시오. 엔티티로 작업하고 있으며 복잡한 편집 (값 변경, 관련 엔티티 추가, 다른 관련 엔티티 제거 등)을 취소하기로 결정했습니다. 그러나 엔티티는 이미 공유 컨텍스트에서 수정되었습니다. 무엇을 하시겠습니까? 힌트 :에 대한 CancelChanges 또는 UndoChanges에 대해 모르겠습니다 ObjectContext.

서버 시나리오에 대해 논의 할 필요는 없다고 생각합니다. 여러 HTTP 요청 또는 웹 서비스 호출간에 단일 엔터티를 공유하기 만하면 응용 프로그램을 사용할 수 없게됩니다. 모든 요청 SaveChanges간에 단일 작업 단위를 공유하므로 모든 요청은 다른 요청에서 부분 데이터를 트리거 하고 저장할 수 있습니다. 이것은 또 다른 문제가있을 것입니다-컨텍스트 및 컨텍스트에서 사용되는 데이터베이스 연결 또는 컨텍스트에서 사용되는 데이터베이스 연결은 스레드 안전하지 않습니다.

읽기 전용 응용 프로그램의 경우에도 응용 프로그램을 쿼리 할 때마다 새로운 데이터를 원할 수 있으므로 전역 컨텍스트는 적합하지 않습니다.


답변

Daniel Simmons에 따르면 :

메소드가 리턴되기 전에 처리되도록 각 서비스 메소드에 대해 Using 문에 새 ObjectContext 인스턴스를 작성하십시오. 이 단계는 서비스 확장 성을 위해 중요합니다. 서비스 호출을 통해 데이터베이스 연결이 열린 상태로 유지되지 않도록하고 해당 작업이 종료 될 때 특정 작업에 사용되는 임시 상태가 가비지 수집됩니다. Entity Framework는 앱 도메인에 필요한 메타 데이터 및 기타 정보를 자동으로 캐시하고 ADO.NET은 데이터베이스 연결을 풀링하므로 매번 컨텍스트를 다시 작성하는 것이 빠른 작업입니다.

이것은 그의 포괄적 인 기사에서 온 것입니다.

http://msdn.microsoft.com/en-us/magazine/ee335715.aspx

이 조언은 HTTP 요청으로 확장되므로 ASP.NET에 유효합니다. WPF 응용 프로그램과 같은 상태 저장 팻 클라이언트 응용 프로그램은 “공유”컨텍스트의 유일한 경우 일 수 있습니다.


답변

EF6 (4,5도) 설명서에 따름 :
https://msdn.microsoft.com/en-us/data/hh949853#9

9.3 요청 당 상황

Entity Framework의 컨텍스트는 최적의 성능 경험을 제공하기 위해 수명이 짧은 인스턴스로 사용됩니다 . 컨텍스트는 수명이 짧고 버려 질 것으로 예상되므로 가능한 한 매우 가볍고 메타 데이터를 재사용하도록 구현되었습니다. 웹 시나리오에서는이를 염두에두고 단일 요청 기간 동안 컨텍스트를 유지하지 않는 것이 중요합니다. 마찬가지로 웹 이외의 시나리오에서는 Entity Framework의 다양한 캐싱 수준에 대한 이해를 바탕으로 컨텍스트를 삭제해야합니다. 일반적으로 말해서, 스레드 당 컨텍스트 및 정적 컨텍스트뿐만 아니라 애플리케이션 수명 동안 컨텍스트 인스턴스를 사용하지 않아야합니다.


답변

아래 코드는 새로운 데이터베이스 값으로 객체를 새로 고치는 데 도움이되었습니다. Entry (object) .Reload () 명령은 객체가 데이터베이스 값을 다시 호출하도록합니다.

GM_MEMBERS member = DatabaseObjectContext.GM_MEMBERS.FirstOrDefault(p => p.Username == username && p.ApplicationName == this.ApplicationName);
DatabaseObjectContext.Entry(member).Reload();


답변