2009-04-19 6 views
2

NHibernate/ActiveRecord 및 WCF와 함께 .net 2.0을 사용하고 있습니다.wcf 직렬화 및 nhibernate 지연로드

지금까지는 NH 지연로드를 사용하지 않았지만 성능 저하는 무시하기에는 너무 커서 사용하기 시작했습니다.

지금까지 읽은 내용은 NH 엔터티를 사용하여 WCF에 게으른로드 및 직렬화를 사용하는 쉬운 주제는 아니지만 이점을 무시하기에는 너무 좋습니다.

여기에서 찾은 코드를 사용하면 : WCF Serialization With NHibernate, WCF에서 기본 유형을 인식 할 수있었습니다.

나는 또한이 같은 DataContractSerializer를 만드는거야 :

public override XmlObjectSerializer CreateSerializer(Type standard, XmlDictionaryString name, XmlDictionaryString NS, IList<Type> knownTypes) 
{ 
    return new DataContractSerializer(standard, name, NS, knownTypes, 0x989680, false, true /* Preserve References*/, new HibernateDataContractSurrogate()); 
} 

나는 이런 일이있을 때 내 문제는 다음과 같습니다

[DataContract, ActiveRecord("POS_POSCUSTOMERS",Lazy = true)] 
public class POSCustomer : ActiveRecordForPOS<POSCustomer> 
{ 
    private Branch belongsToBranch; 

    [DataMember,BelongsTo("BRANCH")] 
    public virtual Branch BelongsToBranch 
    { 
     get { return belongsToBranch; } 
     set { belongsToBranch = value; } 
    } 
} 

[DataContract, ActiveRecord("BRANCHES",Lazy = true)] 
public class Branch : ActiveRecordForPOS<Branch> 
{ 
    private POSCustomer defaultPOSCustomer; 

    [DataMember, BelongsTo("POS_POSCUSTNUM", Cascade= CascadeEnum.None)] 
    public virtual POSCustomer DefaultPOSCustomer 
    { 
     get { return defaultPOSCustomer; } 
     set { defaultPOSCustomer = value; } 
    } 
} 

Branch.DefaultPOSCustomer 및 POSCustomer.BelongsToBranch는 관련이없는 두 개의 엔터티이지만 동일한 엔터티입니다. 예를 들어 Branch 200은 DefaultPOSCustomer 100이고 POSCustomer는 BelongsToBranch 200입니다.

WCF는 개체 그래프를 직렬화하려고하면 DefaultPOSCustomer와 BelongsToBranch 사이에서 동일한 엔터티임을 인식하지 못하는 것처럼 문제가 발생합니다 스택 오버 플로우가 발생할 때까지 이미 직렬화했다고 가정합니다.

이러한 클래스에서 Lazy = true를 해제하면 직렬화가 올바르게 작동합니다.

  1. DataContractSerializer는 엔티티가 이미 serialize되었다고 어떻게 결정합니까?
  2. 어떻게하면이 동작을 멈출 수 있습니까?
  3. WCF로 지연 로딩 엔티티를 직렬화하는 다른 방법이 있습니까?

p.s. 나는 NHibernate Proxy와 비슷한 것을 만들지 만, 다른 클래스와 관련된 프로퍼티를 원시 키로 대체하는 다른 솔루션을 고려해 왔기 때문에 Branch 타입의 프로퍼티 대신 int 타입의 프로퍼티를 가졌을 것이다. 이 방법은 내가 만난 사이클 문제를 피할 수 있을지도 모르지만 최후의 수단으로 이것을 유지하려고 노력할 것입니다. 유지하는 것이 매우 복잡 할 것입니다.

편집 : 나는 엔티티가 많아서 각 엔티티를 작성하는 것이 문제가되지 않으며 동적으로 작성하면 복잡해 지므로 차라리 피하거나 최후의 수단으로 사용하십시오. 또한 서버 측에서 비즈니스 로직을 수행해야하므로 원시 데이터가 아닌 엔티티가 필요합니다.

편집 : 음, 직접 운행하는 NH/AR/WCF 방식입니다. 나는 더 쉬운 것처럼 보이는 DTO를 만드는 것으로 갈 것입니다.

+1

왜 웹 서비스에 사용할 DTO를 만들지 않으십니까? – Paco

답변

2

나는 단지 내 질문을 닫지 않은 것으로 나타났습니다, 나는 DTO 솔루션을 가지고 가서 지금까지 잘 작동합니다.

0

대답하기에는 너무 늦었습니다.하지만 어쨌든, 지연로드 된 객체가 NH 프록시 클래스이므로 발생합니다. 이런 식으로로드 할 때 서로 다른 것처럼 보입니다. 하나의 솔루션은 .Equals()를 재정 의하여 영구 엔터티의 Id 속성을 비교하는 것입니다. 엔티티가 기본 키와 같은 것을 가지고 있다고 생각합니다. 이것은 아마도 WCF가 평등을 사용하고 비교 참조가 아닌 경우에만 행복하게 만들 것입니다. WCF가 항상 ReferenceEquals를 사용한다면 - 운이 없다.

0

우리는 this 솔루션을 사용해 왔으며 DTO 솔루션보다 쉽고/더 나은 것으로 나타났습니다.