6

상황 :사용하여 탐색 속성

  • 코드 첫째, 엔티티 프레임 워크 4.3.1;
  • 사용자 ---- 주제, 1 대 다수 관계;
  • Userpublic virtual ICollection<Topic> CreatedTopics 네비게이션 속성 (Lazy Loading);
  • Topicpublic virtual User Creator 네비게이션 속성;
  • DataServiceController : DbDataController<DefaultDbContext>, 웹 API 베타, ASP.NET MVC 4 베타, 단일 페이지 응용 프로그램.
  • Json 직렬화를위한 System.Json;
  • 웹 API 작업 :

    public IQueryable<Topic> GetTopics() 
    { 
        // return DbContext.Topics;     // OK 
        return DbContext.Topics.Include("Creator"); //With Exception 
    } 
    
  • 결과 : 는 "처리되지 않은 마이크로 소프트 .NET 프레임 워크 예외가 W3wp.exe를 발생는"

문제는 여기 보인다

가되게합니다 : 내가해야 아니 엔티티 내비게이션 속성을 추가 (원인 순환 참조?) 네비게이션 속성을 User 클래스에서 삭제하면 다시 확인하십시오.

그래서, 비슷한 맥락에서 위에 나열된처럼, 여기 제 질문은 다음과 같습니다

많은 관계에 1의 상황에서 탐색 속성을 처리하는 방법
  1. ;
  2. 더 많은 것을 얻으려면 Many to Many 관계는 두 개로 나눌 필요가 있습니까 1 to Many 관계;
  3. 탐색 속성을 사용하기위한 모범 사례 및 예방책은 무엇입니까?

나는 어떤 도움을,

감사를 충분히 명확 많은 관련 게시물 만, 아직도를 :(읽고

답변

9

이 첫 번째 또는 EF 코드의 문제가 아니다! - 그것은 직렬화의 문제입니다. 단순히 웹 API 메시지에서 전달 된 표현으로 객체 그래프를 변환하는 데 사용되는 직렬기를 순환 참조와 함께 사용할 수 없습니다. 사용하려는 메시지 형식에 따라 다른 직렬 변환기가 사용됩니다 기본값은 here입니다. Web API에서 사용하는 기본 직렬 변환기와이를 변경하는 방법에 대해 설명합니다. 다음 텍스트는 DataContractJsonSerializer 또는 DataContractSerializer (XML 직렬화의 경우 기본값이어야 함)이지만 JSON.NET에서도 동일해야합니다 (JSON 직렬화의 기본값이어야 함 - JSON 직렬화는 DataContractJsonSerializer으로 전환 할 수 있지만 기본 직렬 변환기는 더 좋음) .

그럼 어떻게 할 수 있습니까?serializer에게 클래스를 DataContract(IsReference = true)으로 표시하고 전달 된 각 속성을 DataMember 특성으로 표시하여 순환 참조를 추적 할 수 있다고 알려줄 수 있습니다 (JSON.NET을 사용하여 달성하는 방법은 링크 된 문서를 확인하십시오). 이것은 serializer가 사이클을 올바르게 인식 할 수있게하며 이론적으로 serialization이 성공할 것입니다. 왜냐하면 이것은 또한 게으른 로딩을 사용하지 않기를 요구하기 때문입니다. 그렇지 않으면 예상보다 훨씬 많은 데이터를 직렬화 할 수 있습니다 (일부 치명적인 시나리오에서는 데이터베이스의 전체 내용을 직렬화 할 수 있음). 당신이 직렬화 할 때

게으른 로딩 개체 그래프를 사용하면 Topic하고 Creator을 serailze하지만 직렬화도 CreatedTopics 속성을 방문 활성화 => 모든 관련 항목로드 및 직렬화 및 직렬화에 의해 새로로드 주제 Creator 방문을 계속 처리 게으른 ! 이 프로세스는 지연로드 할 다른 개체가 없을 때까지 계속됩니다. 이 때문에 엔티티를 직렬화 할 때 게으른로드를 사용하지 않아야합니다.

다른 옵션은 직렬화에서 역 참조를 제외하는 것입니다. Creator을 직렬화하면됩니다. CreatedTopics을 serialize 할 필요가 없으므로 IgnoreDataMember 속성 (JSON.NET의 경우 JsonIgnore)으로 속성을 표시 할 수 있습니다. 문제는 웹 반환 작업이 User이고 모두 CreateTopics 인 경우 속성 때문에 작동하지 않는다는 것입니다.

마지막 옵션은 엔티티를 사용하지 않습니다. 이 옵션은 일반적으로 특정 작업에 대한 요구 사항을 충족시키는 특수 DTO 객체를 만드는 웹 서비스에서 사용되며 작업 내에서 엔티티와 DTO 간의 변환을 처리합니다 (AutoMapper와 같은 일부 도구를 사용하여 가능).

일대일, 일대 다 또는 다 대다 관계를 처리 할 때 차이점은 없습니다. 양쪽에 탐색 속성이 있으면 항상이 문제를 처리해야합니다.

+0

DataContractJsonSeriaizer가 Web API 베타 용 기본 Json 시리얼 라이저입니까? – Dean

+0

'DataContract (IsReference = true)'와'DataMember'를 일시적으로 사용하고 있는데 이에 대한 자세한 기사가 있습니까? 나는 DTO 옵션에 대해서도 관심이 있지만 지금은 통과하지 못했고, 더 많은 시간을 할애하고 좋은 답변을 주셔서 감사합니다. – Dean