PATCH中使用的OData Delta无法更新嵌套对象

时间:2018-01-16 22:53:52

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

我正在尝试使用Patch方法在Azure Mobile Services项目中创建一个Controller,该方法采用我的实体,结构如下:

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列的表。

不幸的是,调用Patch方法时,Offset_XOffset_Y列不会更新(当它们在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

如何让控制器更新此类属性?或者我应该处理实体的模型吗?

非常感谢任何帮助!!

2 个答案:

答案 0 :(得分:0)

  

注意:此答案适用于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声明为复杂类型时,您将收到类似于此的运行时错误:

  

类型'&lt;您的命名空间&gt; .Point'不能配置为ComplexType。它以前配置为EntityType。

答案 1 :(得分:0)

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

enter image description here

<强> TEST:

enter image description here

  

如何让控制器更新此类属性?或者我应该处理实体的模型吗?

根据我的理解,您可以在Page TableController中修改更新操作并检查Delta<Page> patch下的嵌套对象Point,如果存在特定的Point记录,则更新Point表。但我更希望单独处理每个表的句柄更新。你可以关注adrian hall的关于Relationships的书。此外,您可以构建自己的Custom HTTP Endpoints并自己实现其他逻辑。