2010-08-06 1 views
1

그 제목은 꽤 많이 있습니다. 내가 할 수있는만큼 명확 해 지도록 노력합시다..NET 4, WCF REST Services, 엔티티 프레임 워크, 직렬화 및 순환 참조

.NET Framework 4로 작성된 엔티티 프레임 워크를 사용하여 SQL Server의 일부 데이터를 개체 목록으로 가져 오는 서비스가 있습니다. 그런 다음 객체는 XML로 클라이언트에 반환됩니다. 문제는 모델의 관계로 인해 XML에 서로 참조가 있다는 것입니다.

내 모델 : http://bara.stardock.com/images/activity_model.png

서비스 로직을 처리하는 활동 클래스 :

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 
[ServiceBehavior(IncludeExceptionDetailInFaults = true, InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)] 
public class Activities : IActivities 
{ 
    public ActivitiesList GetActivities(string titleId, string accountId, string numToReturn) 
    { 
     stardockActivitiesEntities sdActivitiesDb = new stardockActivitiesEntities(); 

     int accountIdInt = int.Parse(accountId); 

     List<Activity> items = (from a in sdActivitiesDb.Activities 
           join ab in sdActivitiesDb.ActivityBridges 
            on a.ActivityID equals ab.ActivityID 
           where ab.AccountID == accountIdInt 
           select a).ToList(); 

     ActivitiesList list = new ActivitiesList(items); 

     return list; 
    } 
} 

위 클래스의 인터페이스 :

여기

는 문제를 설명하는 데 도움이되는 몇 가지 코드
[ServiceContract] 
public interface IActivities 
{ 
    [OperationContract] 
    [WebGet(UriTemplate = "{titleId}/accounts/{accountId}/limits/{numToReturn}")] 
    ActivitiesList GetActivities(string titleId, string accountId, string numToReturn); 
} 

활동 클래스는 자동 - 활동 테이블에 대한 내 모델을 기반으로 엔티티 프레임 워크에 의해 생성됩니다. 그러나, 나는이 ActivitiesList 객체를 생성하여이 클래스에 확장 않은 : 그래서, 다시는 내 XML을, 내 문제를 설명하기 위해

[XmlRoot(Namespace = "http://schemas.datacontract.org/2004/07/Stardock.CVP.Stats")] 
public partial class Activity 
{ 

} 

[XmlRoot(Namespace = "http://schemas.datacontract.org/2004/07/Stardock.CVP.Stats")] 
[DataContract(IsReference=false)] 
public class ActivitiesList 
{ 
    [DataMember] 
    public List<Activity> Activities { get; set; } 

    public ActivitiesList() 
    { 
     Activities = new List<Activity>(); 
    } 

    public ActivitiesList(List<Activity> list) 
    { 
     Activities = new List<Activity>(); 

     foreach (Activity item in list) 
     { 
      Activities.Add(item); 
     } 
    } 

    public void Add(Activity a) 
    { 
     Activities.Add(a); 
    } 
} 

을하기보다는 단순히해야 같은 활동의 목록을 반환하는 대신 활동의 목록을 반환 일부 활동은 기본 활동 내에있는 다른 활동을 참조합니다. 즉 혼란 보이지만, 아래 이미지를 보면 :

반환 된 XML : http://bara.stardock.com/images/activity_xml1.png

"I2"의 ID로 활동 내에서 실제로 다른 활동을 언급하고 "I8"의 참조 활동 : http://bara.stardock.com/images/activity_xml2.png

내 질문은, 어떻게하면 Activity 개체에서 모든 추가 관계를 제거 할 수 있습니까? 엔터티 프레임 워크에 의해 자동 생성 된 중첩 된 ActivityType, EntityKey 등이없는 Activity 목록 만 있으면 좋을 것입니다.

나는 충분히 설명했다. 그리고 그렇지 않다면, 당신이보고 싶은 다른 세부 사항을 알려주십시오. 나는 그들을 제공 할 것입니다. 당신은/필요가 없습니다

바라

답변

1

여기에는 두 가지 옵션이 있지만 둘 다 약간의 작업이 필요합니다.

필자가 권장하는 것은 래퍼 클래스를 만들어 적절한 데이터를 노출하고 대신 반환하는 것입니다.

return new PersonWrapper() {Id = Person.Id, Name = Person.이름};

PersonWrapper는 자동 특성 만 있으면되며 반환 할 데이터와 관련 속성을 사용하여 반환하는 방법을 정확하게 제어 할 수 있습니다.

대안 제안이 연습에서 온다 : http://blogs.msdn.com/b/endpoint/archive/2010/01/07/getting-started-with-wcf-webhttp-services-in-net-4.aspx

이 대부분 (대신 규칙에 의해, 엔티티 프레임 워크 코드 생성,지도에 의존 (다시는 수동으로 만들어야 할 것이다) POCO 클래스를 사용하여 제안 사례)를 개념 모델의 엔터티 (http://blogs.msdn.com/b/adonet/archive/2009/05/21/poco-in-the-entity-framework-part-1-the-experience.aspx)

두 번째 옵션을 사용하면 코드 생성을 해제해야하므로 일부 클래스 만 노출하려는 경우에는 모든 엔티티에 대해 수동으로 POCO 클래스를 만들면 객체에 대한 래퍼 클래스를 만드는 것이 좋습니다. 어느 쪽을 드러내야합니까?

마틴

+0

한 동료가 첫 번째 방법을 사용하여 나를 위해 객체를 만든 코드 생성 도구를 작성했습니다. 지금까지 잘 작동하고있는 것 같지만, 이것이 가장 가까운 곳이기 때문에 대답을해야합니다. – Bara

0

당신은 EF (4) 당신이 (예를 들어, 디자이너) 모델의 연결을 제거 할 수 있습니다 사용하는 경우 내 생각은합니다. 그런 식으로 코드 생성기는 관계를 탐색하는 속성을 생성하지 않습니다.

편집 : 연관성이란 실제 연결 (다이어그램의 선) 및 탐색 속성 (엔티티의 아래쪽)을 의미합니다.

+0

나는 그것에 대해 생각했다. 그러나 그 다음에는 그 연관성을 갖는 것이 유용 할 수 없다. 제안 해 주셔서 감사합니다 :) – Bara

관련 문제