如何在一个请求中更新OData实体并修改其导航属性?

时间:2012-09-26 14:59:09

标签: json wcf-data-services odata

我正在尝试使用WCF数据服务提供的OData服务来实现我认为的简单场景(使用OData V3应用程序/ json; odata = verbose有效载荷格式,现在。我可以使用JSON Light格式未来)。基本情况如下:

我有两个实体:

class Person 
{ 
  public int ID { get; set; }
  public string Name { get; set; } 
  public virtual PersonCategory Category { get; set; }
}

class PersonCategory
{
  public int ID { get; set; }
  public string Description { get; set; }
  public virtual ICollection<Person> People { get; set; }
}

现在,我想为Person创建一个简单的编辑页面。此编辑页面可能具有Name的输入,以及Person的Category的输入或下拉。

所以,情景如下:

  1. 代码使用$ expand下载类别:GET /api.svc/People(1)?$ expand = Category
  2. 用户编辑此人的姓名属性及其类别。
  3. 页面代码只发出一个请求来更新该人员的姓名和类别属性。
  4. 这里的关键是“单一请求”。这是我找不到文档的部分。我见过他们将上面的数字3分成两个请求的例子。这样的事情(我不记得确切的格式 - 我也不确定你在做PUT之前是否必须删除Category链接):

    PATCH /api.svc/People(1) with content: {"Name": "new name" }
    PUT /api.svc/People(1)/$links/Category with content: { "url": "/api.svc/Categories(2)" }
    

    但是,我也听说过,但没有证明,可以将此更新作为单个请求实现,并更改为与Person实体的其他更改内联指定的Category导航属性。有人能给我一个如何做到这一点的例子吗?另外,您能告诉我如何使用多对多导航属性,而不是我上面描述的一对多导航属性。

    最后,我目前正在使用详细的JSON格式V3。如果我改为使用新的JSON光格式,您对上述问题的回答是否会有所不同?如果是这样,怎么样?

3 个答案:

答案 0 :(得分:4)

Pratik的评论是答案(如果您想将此作为答案重新发布,请将其标记为 - 谢谢!):

  

问题:是否要更新类别实例,或者是否要更新类别实例的某些属性。除了批处理之外,没有其他方法可以做到。对于前者,您可以执行以下操作:{“名称”:“新名称”,“类别”:{“_ _ metaadata”:{“uri”:“/ api.svc / Category(2)”}}}。希望这可以帮助。 - Pratik

答案 1 :(得分:4)

我找到了两种表示内联导航属性的方法:

application/json;odata=verbose - { "Name": "new name", "Category": { "__metadata": { "uri": "Categories(2)" }}}

application/json - { "Name": "new name", "Category@odata.bind": "Categories(2)" }

答案 2 :(得分:0)

你不再需要批次了。你可以在一个电话中完成。您只需要发送更改的属性并让存储库处理更改的属性。

public class Person 
{
   public string FirstName {get;set;}
   public string LastName {get;set;}
   public int Age {get;set;}
}

让我们说你注意到第一个名字有一个拼写错误,Jhon应该是John。您可以编辑名字并发送。所以你有以下对象模型。您可以通过以下两种方式之一获得此信息:

  • 有两个参数并设置BodyStyle = WebMessageBodyStyle.Wrapped
  • 只需创建一个包含两个属性的通用模型对象:属性1属于T类,属性2属于List。

所以你要发送这个json:

[{ FirstName = 'John' }, ['FirstName']]

现在在服务器端,您可以做您需要做的事情。

如果您不想发送已更改的属性,可以通过选择其值不是默认属性的任何属性来猜测更改的属性。

{FirstName =&#39; John&#39; }

然后,您可以使用一些方法来查看哪些属性已更改: