2011-04-08 4 views
2

WCF를 사용하여 NH 엔티티를 와이어를 통해 보내려고합니다. 게으른로드 된 객체의 복잡한 그래프가 있습니다. serialize 할 때 초기화를 강제 실행하기 위해 사용자 정의 DataContractSurrogate를 구현하려고했습니다. 나는 점점 예외 유지, 그러나WCF로 지연된 엔티티를 직렬화하는 NHibernate

public class HibernateDataContractSurrogate : IDataContractSurrogate 
{ 
    public HibernateDataContractSurrogate() 
    { 
    } 

    public Type GetDataContractType(Type type) 
    { 
     // Serialize proxies as the base type 
     if (typeof(INHibernateProxy).IsAssignableFrom(type)) 
     { 
      type = type.GetType().BaseType; 
     } 

     // Serialize persistent collections as the collection interface type 
     if (typeof(IPersistentCollection).IsAssignableFrom(type)) 
     { 
      foreach (Type collInterface in type.GetInterfaces()) 
      { 
       if (collInterface.IsGenericType) 
       { 
        type = collInterface; 
        break; 
       } 
       else if (!collInterface.Equals(typeof(IPersistentCollection))) 
       { 
        type = collInterface; 
       } 
      } 
     } 

     return type; 
    } 

    public object GetObjectToSerialize(object obj, Type targetType) 
    { 
     if (obj is INHibernateProxy) 
     { 
      obj = ((INHibernateProxy)obj).HibernateLazyInitializer.GetImplementation(); 
     } 

     // Serialize persistent collections as the collection interface type 
     if (obj is IPersistentCollection) 
     { 
      IPersistentCollection persistentCollection = (IPersistentCollection)obj; 
      persistentCollection.ForceInitialization(); 
      obj = persistentCollection.Entries(null); // This returns the "wrapped" collection 
     } 

     return obj; 
    } 

    public object GetDeserializedObject(object obj, Type targetType) 
    { 
     return obj; 
    } 

    public object GetCustomDataToExport(MemberInfo memberInfo, Type dataContractType) 
    { 
     return null; 
    } 

    public object GetCustomDataToExport(Type clrType, Type dataContractType) 
    { 
     return null; 
    } 

    public void GetKnownCustomDataTypes(Collection<Type> customDataTypes) 
    { 
    } 

    public Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData) 
    { 
     return null; 
    } 

    public CodeTypeDeclaration ProcessImportedType(CodeTypeDeclaration typeDeclaration, CodeCompileUnit compileUnit) 
    { 
     return typeDeclaration; 
    } 
} 

: 여기 코드입니다 스택 트레이스를 보면

NHibernate.Exceptions.GenericADOException: could not initialize a collection [SQL trace] ---> System.ObjectDisposedException: Session is closed! 

를,이 라인 persistentCollection.ForceInitialization(); 예외를 던지는 것 같습니다.

어떻게해야합니까?

추신 : 복잡한 NH 엔티티를 직렬화하는 대신 DTO를 사용하고 싶습니다. 그러나 여기서는 불가능합니다.

+0

내가 물어 봐도 왜 당신은 게으른 로딩을 사용합니까? – Aliostad

답변

1

컬렉션이로드 된 NHibernate.ISession 개체를 닫은 후에는 해당 컬렉션을 지연로드 할 수 없습니다. 유일한 옵션은 다음과 같습니다.

  1. 데이터를 직렬화 할 때까지 ISession을 열어 두십시오.
  2. 지연로드를 해제하십시오.
  3. 세션을 닫기 전에 모든 지연로드 된 모음을 가져와야합니다. 여기에 대답 밖으로
관련 문제