2010-08-06 76 views
1

該標題相當滿意。讓我儘可能地做到我能清晰....NET 4,WCF REST服務,實體框架,序列化和循環引用

我有一個WCF REST服務寫在使用實體框架從SQL Server的一些數據拉入對象的列表.NET 4。然後這些對象以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); 
} 

Activity類是自動由實體框架根據「活動」表的模型生成。但是,我沒有這個類通過創建ActivitiesList對象擴展:

[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,而不是簡單地回到它應該像活動的列表,而不是返回活動與列表一些活動參考了基本活動中的其他活動。這聽起來令人困惑,但看看下面的圖片:

返回的XML:http://bara.stardock.com/images/activity_xml1.png

與「6-18」的參考指的是另一項活動,實際上是在活動中與「I2」的ID活動:http://bara.stardock.com/images/activity_xml2.png

我的問題是,我怎麼能刪除所有來自活動對象這些額外的關係?我更喜歡它只是一個沒有由實體框架自動生成的嵌套的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 2010-08-20 20:48:47

0

我想如果你使用EF(4)你可以刪除模型(例如,在設計師)的關聯,你並不需要/想。這樣,代碼生成器不會生成屬性來導航關係。

編輯:通過關聯我的意思是真正的「關聯」(圖中的線)和導航屬性(在實體的底部)。

+0

我想過那個......但是那樣會刪除這些關聯開始的有用性。謝謝你的建議:) – Bara 2010-08-09 15:16:31