我构建了一个暴露几个实体的OData WebAPI服务(使用OData 4,System.Web.Odata v5.1.9)。
该服务接受bost POST(用于创建)和PATCH(用于更新)。在内部,POST和PATCH都转发到Oracle数据库,两种方法都通过一个存储过程处理,该过程将Id作为输入参数。如果Id为null,则创建新记录,否则更新具有该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
}
由于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>
我有一种感觉,我在这里遗漏了一些东西,也许我应该保持原样,但如果没有,我可以采取哪些步骤来确保他们可以正确地调用我的服务
答案 0 :(得分:3)
将float
属性定义为可为空并删除其上的Id
:
KeyAttribute
将public class ContactDTO
{
public int? Id { get; set; }
[ForeignKey("Person")]
public int? PersonId { get; set; }
}
属性配置为键和可选:
Id
它产生以下元数据:
ODataConventionModelBuilder modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntityType<ContactDTO>().HasKey(_ => _.Id);
modelBuilder.EntityType<ContactDTO>().Property(_ => _.Id).IsOptional();