我建立了一个OData WebAPI服务,该服务公开了几个实体(使用OData 4,System.Web.Odata v5.1.9)。
该服务接受POST(用于创建)和PATCH(用于更新)。在内部,POST和PATCH都转发到Oracle数据库,并且这两种方法都是通过单个存储过程处理的,该存储过程将Id作为输入参数。如果Id为空,则创建新记录,否则更新具有该Id的记录。
最近,我们的一位消费者抱怨他们无法正确插入新数据。问题在于他们使用OData客户端使用元数据生成模型。由于Id不可为空,因此始终向我的服务发送0,这提示数据库例程使用ID 0(不存在,引发异常)更新记录。
现在,我看到有两种选择可以避免这种情况:
我的实体类如下所示:
public class ContactDTO
{
[Key]
public int Id { get; set; }
[ForeignKey("Person")]
public int? PersonId { get; set; }
// snip some other properties
}
Run Code Online (Sandbox Code Playgroud)
由于Id属性定义为[Key],因此在元数据中显示为Required:
<EntityType Name="ContactDTO">
<Key>
<PropertyRef Name="Id"/>
</Key>
<Property Name="Id" Type="Edm.Int32" Nullable="false"/>
<Property Name="PersonId" Type="Edm.Int32"/>
</EntityType>
Run Code Online (Sandbox Code Playgroud)
我有一种感觉,我在这里遗漏了一些东西,也许我应该将其保留不变,但是如果没有,我可以采取哪些步骤来确保他们可以正确地致电我的服务
将Id属性定义为可为空,并删除该属性KeyAttribute:
public class ContactDTO
{
public int? Id { get; set; }
[ForeignKey("Person")]
public int? PersonId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)将Id属性配置为键和可选:
ODataConventionModelBuilder modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntityType<ContactDTO>().HasKey(_ => _.Id);
modelBuilder.EntityType<ContactDTO>().Property(_ => _.Id).IsOptional();
Run Code Online (Sandbox Code Playgroud)它产生以下元数据:
<EntityType Name="ContactDTO">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Edm.Int32" />
<Property Name="PersonId" Type="Edm.Int32" />
</EntityType>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1959 次 |
| 最近记录: |