2012-04-17 4 views
1

제가 일하는 곳에서 문제가 있습니다. 우리가 MVC3보기 내에서 NHibernate 엔티티의 지연로드 된 속성에 액세스하려고하면 "세션 없음"LazyInitializationException이 발생합니다. 이것은 지난 주에 시작된 일 이었지만 문제를 좁힐 수 없었습니다. 비록 간단한 해결책이있는 것처럼 보이지 않습니다.MVC3 뷰에서 Lazy Load 된 NHibernate 엔티티

: 스택 트레이스의

  • 예 : http://textsnip.com/613608
  • 우리는 어디서나 우리의 프로젝트를 폐기 할 것 (또는 사용하여 세션을 바꿈)하지 않습니다. ObjectFactory가이를 처리하도록합니다.
  • 은 회귀 테스트를 수행 할 때 TeamCity 테스트 환경에서 발생합니다 (SpecFlow with WatiN). 우리 중 누구도 우리의 개발 컴퓨터에서 문제를 재현 할 수 없습니다.
  • 이 또한 일관되게 발생하지 않습니다. 실패한 테스트는 일반적으로 동일한 테스트이지만 항상 실패하지는 않습니다. 동일한보기 중 일부에 도달하는 페이지에 액세스하는 다른 테스트는 실패하지 않습니다.
  • 테스트에서 실패한 테스트는 비 수집보다 초기화가 느린로드 된 수집쪽으로 무게가 나가는 것 같지만 둘 다 발생합니다.
  • 많은 테이블 모델의 상호 의존성으로 인해 가능할 때마다 엔티티를 열심히로드하는 것이 더 나을 것임을 알고 있지만 현재로서는 그럴 수있는 것이 아닙니다.

여기에 무엇이 누락 되었습니까?

+0

엔티티를 게시하고 조건/쿼리를 nhibernate 할 수 있습니까? – Mariusz

+0

테스트에서 Session을 어떻게 관리합니까? – dotjoe

답변

0

보기에서 개체 모델에 직접 바인딩하고 있습니까? 도메인 개체에 바인딩을 직접 볼 수 있다는 점에서 문제가있는 것 같습니다. 도메인 객체는 게으른 콜렉션을 가지고 있기 때문에 Nhibernate 세션이 필요한 콜렉션 엘리먼트를 요구에 따라로드하려고 시도한다.

컨트롤러 메서드에서 전체보기 모델을 작성해야합니다.

제 제안은 가지고있는 각보기에 대한보기 모델을 만드는 것입니다. 그런 다음 NHibernate를 질의 할 때 모델에 직접 투영하거나 Automapper를 사용하여 객체 모델을 뷰 모델로 변환하십시오. 직접 투영에 대한 좋은 점은 필요한 열만 선택하기 때문에 nhibernate를 통한 쿼리가 더 효율적이라는 것입니다.

이 기사를 참조하십시오. http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/

뷰 모델에 대한 모범 사례 세트입니다.

+0

뷰에서 실제 엔티티를 사용하려고 시도하는 것은 아니오라고 간주되지만, 현재로서는 변경할 수 없다는 점을 잘 알고 있습니다. 또한이 문제는 최근에 수개월 동안 제대로 작동 할 때 시작되었습니다. 우리는 NHibernate 세션이 필요하다는 것을 알고 있습니다. 그래서 우리는 ObjectFactory가 요청별로 생성하기 때문에 모델이 뷰에서 사용될 때 여전히 살아 있어야합니다. – rossisdead

1

엔티티로드 패턴을보기에서 열린 세션이라고하며 이는 안티 패턴으로 간주됩니다. 이 패턴의 단점에 대한 자세한 내용 herehere.

미리 접근 한 데이터가있는 일부보기 모델을 사용하는 것이 좋습니다. 하지만 할 수 없다면 linq을 사용하여 모델 데이터를 미리 가져 와서 확장 확장을 nhibernate 할 수 있습니다. 입력란 확장 확장 기능을 제공하는 오픈 소스 라이브러리 ITDT.Sentia이 있거나 Google에서 "nhibernate expand"를 검색 할 수 있습니다. 더 낮은 수준의 일을 위해서 당신은 nhibernate fetching strategies을 볼 수 있습니다.

예를 들어 ITDT를 사용합니다.Sentia 라이브러리와 가진 다음 모델 : 난 단지 추측 할 수 DEV-환경에서 서로 다른 행동으로

IList<User> users = userRepository 
    .GetAll() 
    .Where(u => /*some constraints*/) 
// here you are telling nhibernate to make a join and eger load what you need 
    .Expand(u => u.Company) 
    .ToList(); 

:

public class User : BaseEntity 
{ 
    public virtual string Email { get; set; } 
    public virtual Company Company { get; set; } 
} 

public class Company : BaseEntity 
{ 
    public virtual string Name { get; set; } 
} 

그리고 사용자를 가져 오는 한 후 회사 법인의 게으른 로딩을 가정, 당신은 뭔가를 할 수 있습니다 그것은 어떻게 든 다른 설정 파일을 사용하고 있습니다. 아마 다른 debug/release web.configs가 있을까요?

관련 문제