【问题标题】:OData Delta used in PATCH cannot update nested objectPATCH 中使用的 OData Delta 无法更新嵌套对象
【发布时间】:2018-01-16 22:53:51
【问题描述】:

我正在尝试在 Azure 移动服务项目中使用 Patch 方法创建一个控制器,该方法采用我的实体,结构如下:

public class Page 
{
        public Page() { }
        public int Color { get; set; }
        public Point Offset { get; set; }
}

Point 类如下所示:

public class Point
{
        public Point() { }
        public double X { get; set; }
        public double Y { get; set; }
}

使用 EntityFramework 使用 CodeFirst 策略创建的模型会生成一个包含 ColorOffset_XOffset_Y 列的表。

不幸的是,Offset_XOffset_Y 列在调用 Patch 方法时没有更新(虽然它们在 Post 方法中正确填充)。

我的 PATCH 请求正文如下所示:

{
 "Color":16755404,
 "Offset": {
   "X":20.0,
   "Y":40.0
 }
}

我正在使用以下 NuGet 包:

  • Microsoft.Data.OData.5.8.3
  • Microsoft.Data.Edm.5.8.3
  • Microsoft.AspNet.WebApi.OData.5.7.0
  • Microsoft.Azure.Mobile.Server.2.0.0

如何让我的控制器更新这些属性?还是我应该研究实体模型?

非常感谢任何帮助!

【问题讨论】:

  • 请提供您在 PATCH 请求中发送的 json 有效负载,以确认。
  • 您使用的是什么版本的移动服务 SDK - 答案可能大不相同
  • 我添加了 PATCH 的主体 + 使用的 SDK

标签: c# entity-framework odata azure-mobile-services


【解决方案1】:

注意:此答案适用于 Microsoft.OData.Core nuget 包提供的 OData v4,不适用于 Azure 移动服务

由于它目前在 Microsoft.Data.OData 中实现,因此您无法修补嵌套实体,但可以修补复杂类型实体的属性。 对您的模型来说,好消息是 Point 已经在您的实体模型中实现为映射的复杂类型,但是您所描述的行为让我相信 OData 模型不具有相同的解释

对于您的示例,这是一个可能的 odata 模型构建器语句:

var builder = new ODataConventionModelBuilder();
// Complex Type Overrides
builder.ComplexType<Point>();
// EntitySet Declarations
builder.EntitySet<Page>("Page");

当您想要覆盖模型中类的默认解释时,您必须在标准 EntitySet 声明之前声明它们,否则当 Page 被声明为 EntitySet 时,它的属性会立即包含在模型,当您尝试将 Point 声明为复杂类型时,您将收到类似以下的运行时错误:

类型“.Point”不能配置为 ComplexType。它之前被配置为 EntityType。

【讨论】:

  • 感谢您的示例 + stackoverflow.com/questions/32395116/… 的内容,我能够使 GET 请求工作,但 PATCH 仍然没有运气。问题似乎是作为 PATCH 方法输入的 Delta 对象无法识别嵌套对象 Point,因此无法提供 Changed vs Unchanged 属性列表
【解决方案2】:

根据您的描述,我也测试了这个问题,可能会遇到与您提供的相同的问题。另外,我发现我们可以为嵌套对象 Point 提供一个新的id 属性,用于插入如下:

测试:

如何让我的控制器更新这些属性?还是我应该研究实体模型?

根据我的理解,您可以在 Page TableController 中修改更新操作并检查 Delta&lt;Page&gt; patch 下的嵌套对象 Point,如果存在特定的 Point 记录,则更新 Point 表。但我更愿意单独处理每个表的更新。你可以关注阿德里安·霍尔关于Relationships 的书。此外,您可以构建您的Custom HTTP Endpoints 并自行实现附加逻辑。

【讨论】:

  • 感谢您的贡献。实际上,我想避免为 Point 使用全新的表;相反,我只会使用 Point 类作为一组列的容器,这些列在 DB 中只是 Page 表的列。
猜你喜欢
  • 1970-01-01
  • 2021-01-24
  • 1970-01-01
  • 2013-11-27
  • 1970-01-01
  • 2018-06-04
  • 2018-12-23
  • 2020-05-22
  • 1970-01-01
相关资源
最近更新 更多