2011-03-03 2 views
0

내 수업에서 lazy = "true"를 사용하면 응용 프로그램이 완벽하게 작동하지만 성능은 끔찍합니다. 튜토리얼에서 이것을 만들었을 때 나는 가능한 한 빨리 작동하도록하고 싶었습니다. (나는이 튜토리얼을 사용했다 : http://geekswithblogs.net/BobPalmer/archive/2010/04/23/mapping-object-relationships---quickstart-with-nhibernate-part-3.aspx은 빠르게 작동하는 것을 얻는 데 매우 도움이되었다)게으른 로딩이 NHibernate와 작동하지 않는다

하나의 객체 만 사용해야 할 때 이러한 다 대일 클래스를 모두로드 할 필요는 없다. 게으른 로딩을 다시 켜는 것이 이치에 맞습니다. 그런 다음, 객체를 들여다 보았고, 주요 객체 내에서 다 대일 (many-to-one) 클래스에 대한 예외를 보았습니다. 나중에 이러한 속성을 사용하려고하면 나는 다음과 같은 오류 얻을 :이 세션이 닫혀 있음을 의미 같은데요

"Could not initialize proxy - no Session." 

을, 너무 게으른 -로드 추가 개체를 시도 할 때 오류가 발생합니다. 내 세션 제공자는 다음과 같이 (자습서와 동일) 모양 : 다음과 같이 내 저장소에서 사용하는

class SessionProvider { 
    private static ISessionFactory _sessionFactory; 
    private static Configuration _config; 

    public static ISessionFactory SessionFactory { 
     get { 
      if (_sessionFactory == null) { 
       _sessionFactory = Config.BuildSessionFactory(); 
      } 
      return _sessionFactory; 
     } 
    } 

    private static Configuration Config { 
     get { 
      if (_config == null) { 
       _config = new Configuration(); 
       _config.AddAssembly(Assembly.GetCallingAssembly()); 
      } 
      return _config; 
     } 
    } 
} 

:

private static ISession GetSession() { 
     return SessionProvider.SessionFactory.OpenSession(); 
} 
:이 기능에서 세션을 얻을 수

using (var session = GetSession()) { ... } 

내 질문이 여기에 무엇을 할 것으로 예상됩니까? 세션을 열린 상태로 유지 하시겠습니까? 모든 저장소에서 정적으로 만드시겠습니까? 나는 NHibernate가 어떻게 작동하는지 충분히 이해하지 못했다. 내 우선 순위는 현재 차이점이 있다면 데이터베이스에서 읽는 것뿐입니다. 이것은 궁극적으로 우리의 웹 사이트와 다양한 C# .Net 응용 프로그램 모두에서 사용될 코드 라이브러리에 있습니다.

답변

2

unit of work pattern을 사용하는 것이 좋습니다. 특정 엔티티가 필요하다고 생각되면 열심히로드하는 것이 좋습니다.

+0

다음 두 도움말은 도움이되었습니다. http://blogs.hibernatingrhinos.com/nhibernate/archive/0001/01/01/the-repository-pattern.aspx 및 http://nhforge.org/wikis/patternsandpractices/nhibernate- and-unit-of-work-pattern.aspx이 질문에 대한 대답으로 표시 하겠지만 웹 응용 프로그램 및 Windows 응용 프로그램에서이 문제를 사용하려고 할 때 일어날 일에 대해 더 알고 싶습니다. 응용 프로그램 유형에 따라 두 세션을 제공하는 방식을 전환 할 무언가를 만들어야합니까? – Chris

+0

Windows 응용 프로그램의 경우 연결이 끊어진 세션을 사용하거나 화면 당 하나의 세션을 원할 수 있습니다. 여기서도 작업 단위 패턴을 계속 사용할 수 있습니다. 그러나 동일한 데이터베이스에서 많은 클라이언트를 사용하지 않도록 서버를 고려해야합니다. – jonnii

+0

네,하지만 이것을 웹 응용 프로그램에서도 사용할 것입니다. 응용 프로그램이 ASP.Net 응용 프로그램에서 실행되고 있는지 여부를 어떻게 확인할 수 있습니까? HttpContext를 확인해야하지만 기본적으로 활성화되어 있지는 않습니다. 단순히 그것을 사용하도록 설정하고 null인지 확인하는 것이 가장 좋은 방법은 아닙니다. – Chris

0

응용 프로그램이 웹 응용 프로그램 (예 : ASP.NET MVC)인지 또는 콘솔/GUI/서비스 응용 프로그램인지 여부는 알 수 없습니다. MVC 웹 응용 프로그램에서 지연로드 ORM의 일반적인 문제점은 컨트롤러의 액션 메소드가 끝날 때 세션이 닫히고 프록시 엔티티 객체가 뷰로 전달되어 뷰에 전달되어 지연된 일부 콜렉션을 열거하려고 시도한다는 것입니다. 세션이 폐기되었습니다. 이에 대한 해결책은 일반적으로 웹 요청 시작시 세션을 여는 필터를 사용하여 세션이 모든 컨트롤러 또는 다른 서버로 전달되는지 확인하는 'Java 세션에서 열린 세션보기'패턴이라고합니다. (일반적으로 IoC 컨테이너에 의해 관리 될 것입니다), 뷰가 실행 중이고 lazy-loads 프로퍼티 일 때 세션은 여전히 ​​활성화되어 있습니다.

몇 가지 시스템에서 Java와 .Net 모두에 대해 최대 절전 모드로 작업했기 때문에 일반적으로 느린 로딩은 저주라고 생각합니다. 편리하기는하지만 (종종 'View in View'패턴을 지원하는 것과 같은) 추가 배관 작업이 필요하며 자주 성능이 저하됩니다. 아마도 액세스 가능성이 높은 콜렉션에 대해 열망하는로드를 사용하는 것이 좋습니다. 열심히로드해야하는 콜렉션을 분석하면 앱의 데이터 액세스 프로파일을 더 잘 이해할 수있게되므로 애플리케이션의 성능 특성을 훨씬 잘 이해할 수 있습니다. 이는 좋은 것일뿐입니다!

+0

이것은 ASP.Net 응용 프로그램과 다른 Windows 응용 프로그램에서 모두 사용되는 클래스 라이브러리입니다. 현재 실제로 수행하려고 시도하는 것은 저장 프로 시저에서 더 잘 수행 될 것이지만, 나도 그렇게하지 않으면 다시 작동 할 것이기 때문에 지연로드를 얻는 방법을 알고 싶습니다. – Chris

1

세션을 리포지토리에서 열고 닫음으로써 세션을 미세 조정합니다. 게으른로드가 끊어 질뿐만 아니라 성능이 많이 손상됩니다.

대신 세션 관리를 좀 더 거친 방법으로 수행해야합니다.예를 들어

은 웹 응용 프로그램, 하나 개의 권장 패턴은 session-per-request (세션이있는 HttpContext를 열고 모듈 또는 전역 핸들러에 의해 폐쇄 및 바인딩)

그냥 세션 당 찾아이다 -request, 많은 예제가 있습니다.

0

간단한 문제는 엔티티의 관련 세션이 삭제되었을 때 아직 지연로드 된 값에 액세스하려고하는 것입니다.

NHibernate의 Session 개체는 작업 단위 패턴을 따르기위한 개체입니다. 즉, 완료하려는 모든 유닛에 대해 하나의 세션을 생성합니다.

분명히 말해서 해당 세션과 연결된 개체가 "완료"될 때까지 Session 인스턴스를 활성 상태 (처리되지 않음)로 유지해야합니다. 이 세션 객체가 작업의 범위가됩니다 것을 의미합니다 :

using(var session = GetSession()) 
{ 
    // Load some objects. 
    // Manipulate some values. 
    // Commit changes. 
} 

자 NHibernate 세션은 모든 단계가 세션의 범위 내에서 완료해야하는 광범위한 작업을 완료하는 데 필요한 데이터베이스 트랜잭션, 유사하게 취급되어야한다 .

관련 문제