这个头衔非常令人满意 . 让我试着尽可能清楚......
我有一个用.NET 4编写的WCF REST服务,它使用实体框架将一些数据从SQL Server提取到一个对象列表中 . 然后将对象作为XML返回给客户端 . 问题是由于我的模型关系,XML互相引用 .
以下是一些有助于说明问题的代码:
我的型号:http://bara.stardock.com/images/activity_model.png
处理服务逻辑的Activities类:
[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类是由实体框架根据我的Activities表模型自动生成的 . 但是,我确实通过创建一个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等,它们是由实体框架自动生成的 .
我希望我已经充分解释了自己 . 如果没有,请告诉我你想看到的其他细节,我会提供给他们 .
巴拉
2 回答
这里有两个选项,但是它们都需要一些工作 .
我的建议是创建包装类,公开适当的数据并返回它们 .
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类可能会很麻烦,这就是我建议只创建包装类的原因 . 对于需要暴露的物体
马丁
我想如果你使用EF(4)你可以删除你不需要/想要的模型中的关联(例如在设计器中) . 这样,代码生成器不会生成用于在关系上导航的属性 .
编辑:通过关联,我指的是真正的“关联”(图中的线条)和导航属性(在实体的底部) .