2010-08-06 77 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