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

Json 如何在一个请求中更新OData实体并修改其导航属性?,json,wcf-data-services,odata,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;

我正在尝试使用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实体的其他更改内联指定。有人能给我举个例子说明如何做到这一点吗?另外,您能告诉我如何使用多对多导航属性来实现它,而不是我上面描述的一对多导航属性


最后,我目前使用的是详细的JSON格式V3。如果我改用新的JSON light格式,您对上述问题的回答会有所不同吗?如果是,如何回答?

Pratik的评论就是答案(Pratik如果你想将此作为答案转载,我将标记为这样-谢谢!):


问题:是要更新类别实例还是要更新类别实例的某些属性。除了批处理之外,没有其他方法可以进行后续操作。对于前者,您可以执行以下操作:{“名称”:“新名称”,“类别”:{“\uu元数据”:{“uri”:“/api.svc/Categories(2)”}}。希望这能有所帮助普拉蒂克


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

应用程序/json;odata=verbose
-
{“名称”:“新名称”,“类别”:{“元数据”:{“uri”:“类别(2)”}}


应用程序/json
-
{“名称”:“新名称”Category@odata.bind“:“类别(2)”}

您不再需要批处理。你只需一次电话就可以做到。您只需发送更改的属性,并让存储库处理更改的属性

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为列表
因此,您将发送此json:

[{ FirstName = 'John' }, ['FirstName']]
现在在服务器端,您可以做您需要做的事情

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

{FirstName='John'}

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

  • 自定义每个实体的代码,以确保每个属性不是默认值并进行设置。每个实体需要一段代码
  • 反射以确保每个属性不是默认值。所有实体都需要一个类。我早在2014年就在实体框架中这样做了:

您可以发送一个批处理请求-这将是一个包含两个操作的单个请求。除了批处理请求之外,没有其他方法可以执行此操作吗?这会给客户端的往返代码增加一些额外的复杂性,这是我希望避免的。理想情况下,我只想将我的补丁/api/Activity(1)请求的格式设置为:{“category”:{“\uu deferred”:{“uri”:“/api.svc/Categories(2)”}}}这样似乎不起作用。我得到一个204响应,但服务器端的属性保持不变。WCF数据服务不支持所谓的深度更新(这是您在这里想要的)。事实上,即使是OData本身也没有真正定义它。在某些情况下,它可能变得相当复杂。恐怕批次是唯一的解决办法。但支持深度插入(但同样仅支持插入,不修改任何现有内容)。问题:是否要更新类别实例或类别实例的某些属性。除了批处理之外,没有其他方法可以进行后续操作。对于前者,您可以执行以下操作:{“名称”:“新名称”,“类别”:{“\uu元数据”:{“uri”:“/api.svc/Categories(2)”}}。希望这能帮上忙。很抱歉回复太晚。是的,前一个。我不想更新类别实例的属性-只需将Person实例的类别更新为不同的类别。当我使用链接元数据的完整url\uri时,Hmm会起作用,好吧。第一个示例是OData 3.0规范。第二个示例是OData 4.0
[{ FirstName = 'John' }, ['FirstName']]