2011-02-04 2 views
0

내 DTO에는 내 데이터베이스에서 사용하는 ID가 있으며 대개 자동 증가 INT입니다. 내 응용 프로그램은 일반적으로이 ID 필드를 신경 쓰지 않으며 Name 속성으로 DTO를 조회하는 경향이 있습니다. 어떤 내 데이터 액세스 레이어에서이 방법을 굴복했습니다속성 이름 별 nHibernate Session.Load

이 내 DTO들의 대부분을로드하는 방법이기 때문에 내가 발견 한 것을 이제
public T GetByName(string name) 
{ 
    return (T) Session 
     .CreateCriteria(typeof (T)) 
     .Add(Expression.Eq("Name", name)) 
     .UniqueResult(); 
} 

는 nHibernate 수는 결과를 캐싱되지 않는 것입니다. SQL Profiler를 통해이 메소드를 호출 할 때마다 데이터베이스에 대한 왕복이 발생한다는 것을 알았습니다. 작업 단위 중에이 특정 객체를로드했는지는 확실합니다. HTTP 트랜잭션).

또한, 내가 읽은 바는 .Load()를 호출 할 때 nHibernate가 1 차 캐시에서 DTO를 캐싱한다는 것이다.

내 질문 :이 방법으로로드 된 후 첫 번째 수준의 캐시에 내 DTO를 넣으려면 nHibernate를 구성하는 방법이 있습니까? 아니면 데이터베이스 왕복을 줄이기위한 다른 방법을 찾아야합니까?

답변

2

코드에 몇 가지 문제가 있습니다. 쿼리를 캐시하지 않는

  1. 기준 항상의 DB로 이동합니다. SetCacheable을 사용해야하고 캐시 공급자를 구성하고 enable query caching을 사용해야합니다.
  2. NHibernate는 엔티티 자체가 아닌 그 질의로 인해 생성 된 객체 ID를 저장하기 때문에 쿼리를 캐시해도 여전히 make the entity cacheable이 필요합니다.
  3. "1 차 레벨 캐시"는 작업 단위 (세션)입니다. 쿼리가 아닌 GetLoad 메서드를 사용하여 상호 작용합니다. 작은 예외 : 세션에 이미로드 된 엔터티은 DB에서 다시 읽을 필요가 없습니다.
0

NHibernate는 기본 키로로드하지 않는 한 1 차 레벨 캐시에서 엔티티를 캐시하지 않습니다.

나는이 같은 상황을 뒤로하고있다. 기본 키에 의해로드되지 않은 엔티티가 두 번째 레벨 캐시에 캐시 될지 여부를 결정한 적이 없습니다 (캐시를 사용하는 경우). 아마도 다른 사람이 대답을 제공 할 수 있습니다.

+0

두 번째 수준 캐시에 캐시되는 내용은 두 번째 수준 캐시 구성을 통해 결정됩니다. 이 경우 실제로 쿼리를 실행하여 개체를 검색하므로 쿼리 결과 캐싱이 켜져 있어야합니다. –

0

natural-id를 이름 필드로 정의하면 어떨까요? nHibernate가 스키마 생성에만 이것을 사용하는지는 모르겠지만, nHibernate가 스키마 생성을 실제로 수행 할 것인지에 관계없이 이것이 이것을 정의하는 자연스러운 장소라는 것은 의미가 있습니다. 그렇지 않은 경우 잘못된 기능 요청이 아닙니다.