1

这个标题真够拗口的。让我尽量说清楚...

我有一个用 .NET 4 编写的 WCF REST 服务,它使用实体框架将一些数据从 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);
}

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 不是像它应该的那样简单地返回一个 Activity 列表,而是返回一个 Activity 列表,其中一些活动引用了基本活动中的其他活动。这听起来令人困惑,但请看下面的图片:

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

引用“i8”的活动是指实际在活动内部的另一个活动,ID 为“i2”:http ://bara.stardock.com/images/activity_xml2.png

我的问题是,如何从 Activity 对象中删除所有这些额外的关系?我希望它只是一个 Activity 列表,没有由实体框架自动生成的嵌套 ActivityType、EntityKey 等。

我希望我已经充分解释了自己。如果没有,请告诉我您还想查看哪些其他详细信息,我会提供。

巴拉

4

2 回答 2

1

这里有两个选项,但是它们都需要一些工作。

我的建议是创建包装类来公开适当的数据并返回它们。

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

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 类可能会很痛苦,这就是为什么我建议只创建包装类对于需要暴露的对象

马丁

于 2010-08-20T00:40:22.320 回答
0

我猜如果您使用 EF(4),您可以删除模型中(例如在设计器中)您不需要/不想要的关联。这样,代码生成器就不会生成属性来导航关系。

编辑:关联是指真正的“关联”(图中的线)和导航属性(在实体的底部)。

于 2010-08-07T12:24:42.260 回答