OData客户端无法为Key属性发送空值

时间:2016-12-21 08:23:56

标签: c# odata

我构建了一个暴露几个实体的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更新记录(不存在,引发异常)。

现在,有一些我认为可以避免这种情况的选择:

  • 在我的控制器中检查Id是否为默认值(int),如果是,则将NULL传递给SP
  • 停止使用OData客户端并让他们手动构建消息
  • 将单个存储过程分成两个过程(插入和更新)
  • 将Id属性更改为字符串

我的实体类看起来像这样:

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>

我有一种感觉,我在这里遗漏了一些东西,也许我应该保持原样,但如果没有,我可以采取哪些步骤来确保他们可以正确地调用我的服务

1 个答案:

答案 0 :(得分:3)

  1. float属性定义为可为空并删除其上的Id

    KeyAttribute
  2. public class ContactDTO { public int? Id { get; set; } [ForeignKey("Person")] public int? PersonId { get; set; } } 属性配置为键和可选:

    Id
  3. 它产生以下元数据:

    ODataConventionModelBuilder modelBuilder = new ODataConventionModelBuilder();
    
    modelBuilder.EntityType<ContactDTO>().HasKey(_ => _.Id);
    
    modelBuilder.EntityType<ContactDTO>().Property(_ => _.Id).IsOptional();