2009-11-09 2 views
6

나는 두 개의 연관된 비즈니스 객체 -A와 B를 가지고있다. B.Id a와의 연관은 (A-> B) many-to-one이다. A의 외래 키 (A는 DB에 A.B_id가 있음).NHibernate - 전체 객체를 지연로드하지 않고 연관된 객체의 ID에 접근한다.

나는 Lazy = true를 사용하고 있으며 대부분의 문제점 ( )을 해결했습니다. A 's ToString에서는 A.B.Id를 인쇄하려고합니다. 더 이상 DB를 사용하지 않고 가져 가야합니다. A.B에 액세스하면 프록시가 활성화되고 이는 열린 세션의 컨텍스트가 아니기 때문에 예외를 throw합니다.

쉽지 만 못생긴 해결책은 A.B_id 속성을 갖는 것입니다. 그러나 그것은 우리가 처음에 피하려고했던 것들의 일부입니다. 이 작업을 수행하는 "유기적 인"방법이 있습니까? :) 감사합니다!


업데이트 : 그냥 캐싱 및 Session.Get 대 Session.Load에 대해 읽었습니다. 그 전에는 객체가 존재하지 않으면 (Session.Load), 다른 객체가 null 객체 (Session.Get)를 반환하면 예외가 throw됩니다. here 캐싱에 대해 읽은 후에는 Session.Load가 객체에 대한 프록시를 반환하고 ID 이외의 속성에 액세스 할 때 지연 연결 만 가져옵니다. 이는 연결에서 필요한 것과 매우 비슷합니다. 지금은 별도의 객체 ID를 추가했습니다. (ABId를 사용하여 ABId 대신 A.B_Id로 액세스 할 수 있도록 A에 B_Id를 추가했습니다.)

+0

왜이 작업을 수행 하시겠습니까? – Paco

+0

내가 말했듯이, A의 ToString()에서 로그 인쇄 등을 위해서만 사용됩니다. B의 다른 필드는 필요하지 않습니다. –

답변

3

정확히 동일한 이유로 모든 내 많은 AB-ID 속성을 사용했습니다. - 대 - 일 관계. 나는이 문제에 대한 해결책을 제공하기 때문에 빠르고 더러운 해결책으로 보이지 않는다. 또한 유연성을 많이 가지는 것은 저축 업데이트 영역이다. 즉 데이터베이스에서 B 객체를 가져 와서 A에 할당 할 필요가 없다. 쿼리 문자열이나 다른 곳에 B_ID가있을 때 연관을 만들려면

내 매핑 파일 useually 다음과 같이 :

<property name="CreatorID" column="CreatorID" type="Int32" not-null="true" /> 
<many-to-one name="Creator" column="CreatorID" class="SystemUser" insert="false" update="false" cascade="none" /> 

당신이 두 속성 중 하나를 볼 수있는 것은 NHibernate에가 삽입 또는 updatas이 데이터베이스에 2 번이 열을 보내는 것을 피하기 위해 읽기 전용으로한다 사고. 위의 내용은 many-to-one은 insert = "false"update = "false"속성을 사용하여 읽기 전용으로 만 만들었지 만 원하는 경우 CreatorID 속성 만 읽을 수 있습니다.

다 대일 만있는 경우 엔티티 클래스 A에 B.ID 값을 보유 할 속성이 없습니다. 그것을 얻는 유일한 방법은 프록시를 트리거 할 B 오브젝트에 액세스하는 것입니다 (데이터베이스 세션이 이미 세션에로드되어 있지 않은 경우).

솔루션을 제공하고 동일한 종류의 유연성을 제공하는 다른 옵션을 알려 드리겠습니다.

using NHibernate.Proxy; 
... 
object id = null; 
if (obj.IsProxy()) // obj is the object you want to get its identifier. 
{ 
    var proxy = obj as INHibernateProxy; 
    if (proxy != null) 
    { 
     var li = proxy.HibernateLazyInitializer; 
     if (li != null) 
      id = li.Identifier; 
    } 
} 
+0

ABId를 사용하여이 작업을 수행 할 수 있기를 바랍니다. 중복 데이터가 마음에 들지 않습니다. 이러한 속성을 가지고 * 삭제했습니다. . 감사! –

+0

@YonatanKarni 완전히 동의합니다. 또한 이와 관련된 주요 성능 문제가 있습니다. 많은 수의 n 개의 '프록시'엔티티를 엔티티 컬렉션 (설정된 백업 유형이있는)에 추가하면 n set (프록시 당 하나)이 순차적으로 수행되므로'set.Add ' 맡은 일. – jasper

5

, 당신은 전체 개체를로드하기 위해 데이터베이스에 다른 왕복없이 관련 개체의 ID를 얻기 위해 다음 코드를 사용할 수 있습니다 Nhibernate 세션 :

session.GetIdentifier(obj); 
1

당신은의 GetIdentifier 방법을 사용할 수 있습니다 : 당신이 NHibernate에 3.2 이상을 사용하는 경우

관련 문제