2012-09-25 2 views
3

Car Histories가있는 데이터베이스가 있습니다. 각 차량 기록에는 여러 개의 이미지가 연관되어 있습니다. 나는 관계를 설정하는 NHibernate에 2.2을 사용하고하고 CarHistory 매핑은 이미지의 가방을 포함JSON.NET 및 nHibernate, 직렬화시 지연된 객체를 무시합니다.

<bag name="Photos" table="DetailPhoto" cascade="all" lazy="true"> 
    <key column="CAR_DETAIL_ID"/> 
    <one-to-many class="DetailPhoto"/> 
</bag> 

내가 JSON을 사용하여 서버와 통신하는 아이 패드 응용 프로그램을 가지고있다. 나는 모든 자동차 기록 항목을 iPad의 목록에로드하려고하며 목록을로드 할 때 사진을 포함시키지 않으므로 데이터 검색 속도가 느려지므로 사진을 게으르게 만들었습니다.

JsonConvert.SerializeObject를 사용하여 Car Histories의 목록을 직렬화 할 때 사진과 JsonSerializer가 필요 없기 때문에 내 객체를로드하고 세션을 닫았 기 때문에 지연 초기화 예외가 발생합니다. 객체의 모든 속성을 터치합니다.

사진이없는 클라이언트에게 Json 데이터를 반환하고 싶지만 다른 상황에서이 컬렉션을로드하려고하기 때문에 객체에서 JsonProperty를 무시할 수 없습니다. 나는

public class CarDetail 
{ 
    [JsonProperty("id")] 
    public virtual int Id { get; set; } 

    [JsonProperty("carId")] 
    public virtual int CarId { get; set; } 

    [JsonProperty("date")] 
    public virtual DateTime ? Date { get; set; } 

    [JsonProperty("details")] 
    public virtual string Details { get; set; } 

    [JsonProperty("photos")] 
    public virtual IList<DetailPhoto> Photos { get; set; } 
} 

그래서 제 질문은 어떻게 (CarDetail) 클래스를 할 수 http://www.royjacobs.org/2011/07/27/using-json-net-to-serialize-proxied-nhibernate-objects/

이 내 CarHistory입니다 :

나는 이것을 시도했지만 그것은 단지 나에게 게으른 초기화 예외를주고 같은 일을 일부 상황에서는 관련 사진이없는 CarHistorories 목록을 검색하고 다른 곳에서는 그렇지 않습니다.

답변

0

이와 같은 경우에는 "연결된"도메인 객체와 직렬화 형식 사이에 레이어를 만들어야합니다. 일반적으로 도메인 모델 객체와 비슷한 데이터 전송 객체를 만들지 만 대개 직접 연결이없고 대신 ID 목록 만 포함합니다. 그런 다음 Automapper을 사용하여 데이터 전송 객체와 도메인 객체 사이를 매핑합니다.

+0

이렇게하면 CarHistory 목록에 하나의 DTO가 필요하고 CarHistory를 표시하기 위해 별도의 DTO가 필요하다는 의미입니까?그리고 목록 DTO에서 JSON 속성을 무시하고 디스플레이 DTO에 포함 시켰습니까? 나는 DTO의 폭발로 끝날 것이고 모든 것을 더 복잡하게 만들 것이기 ​​때문에 이것을 피하려고했습니다. – Asagohan

+0

클라이언트 측에서는 JSON 데이터를 모든 연관성이있는 Objective C 객체로 다시 매핑하는 RESTKit을 사용하고 있기 때문에 좋은 결과를 얻었습니다. ID 만 있으면 더 이상 할 수 없다고 생각합니까? – Asagohan

+0

DTO 항목을 알고 있고 직렬화 할 수 있으므로 CarHistory DTO 목록을이 경우 물론 모델링 할 수 있습니다. 예를 들어, 도메인 모델에서 실제로 '자동차'여야하는 'CarId'와 같은 경우에 들어갑니다. 자동차의 ID를 알고 양측에 Car 엔티티가 있음을 알게되면 직렬화 할 필요가 없으므로 느리게 또는 다른 방법으로로드 할 필요가 없습니다. 일단 DTO를 직렬화하고 전송하면, 그것을 역 직렬화하고 (무엇이든간에 사용하여) 도메인 객체에 역 매핑 할 수 있습니다. – codekaizen

0

기본 계약자 직렬화 기는 모든 항목을 직렬화하려고 시도하며, 아직로드되지 않은 항목에 도달하면이를 인식하지 못하고 직렬화하려고 시도합니다. 그러면 프록시가 데이터로드를 시도하여 성능 문제 (1 + n + n^2 + .. 쿼리)가 발생하거나 단순히 세션이 이미 종료 된 경우 즉시 예외가 발생합니다. 첫 번째 장소.

사용자 지정 계약 확인자를 사용하면 은로드되지 않은 컬렉션 및 속성을 serializer가 직렬화하지 않도록 serializer에 지시 할 수 있습니다. 아니면 예외를 더 잘 던지거나 로그인하십시오.

비슷한 문제를 참조하십시오 : JSON.Net Serialization of NHibernate Proxies (NH 3.3.2.4000) - 사용자 정의 ContractResolver 예제를 찾을 수 있습니다.

문제가 다르므로 자신의 ContractResolver를 작성할 때, 그 안에 당신이 예를 들면, 속성-에이 - - 직렬화 필터링해야하기 때문에 그것은,하지만 당신의 요구에 완료 할 것

:

var propertyInfo = (PropertyInfo)member; 
var value = propertyInfo.GetValue(target); 
var shouldSerialize = NH.NHibernateUtil.IsInitialized(value); 

하는 이 속성에 프록시되고 아직로드되지 않은 컬렉션 또는 개체 참조가 속성에 포함되어 있으면 false이 생성됩니다.

관련 문제