我正在使用OData V4.0 API,我正试图围绕如何正确创建实体。我正在使用此OData V4.0 reference service。
我的“天真”假设(基于大多数数据库的工作方式)是,当将实体POST到集合时,我会省略主键并让服务生成它并在响应中将其返回给我。
换句话说,当我提出以下请求时:
POST http://services.odata.org/Experimental/OData/(S(<SessionID>))/OData.svc/Products
Content-Type: application/json
{
"@odata.type": "ODataDemo.Product",
"Name": "Widget",
"Description": "A simple widget",
"ReleaseDate": "1991-01-01T00:00:00Z",
"DiscontinuedDate": null,
"Rating": 4,
"Price": 2.5
}
我希望得到状态代码为201 Created
且Location
标头为http://services.odata.org/Experimental/OData/(S(<SessionID>))/OData.svc/Products(11)
的答案。
相反,我收到以下错误:
The serialized resource has a null value in key member 'ID'.
Null values are not supported in key members.
所以我想,也许我可以将它设置为任意值,服务将简单地忽略它并发出自己的ID。所以我尝试以下请求:
POST http://services.odata.org/Experimental/OData/(S(<SessionID>))/OData.svc/Products
Content-Type: application/json
{
"@odata.type": "ODataDemo.Product",
"ID": 0,
"Name": "Widget",
"Description": "A simple widget",
"ReleaseDate": "1991-01-01T00:00:00Z",
"DiscontinuedDate": null,
"Rating": 4,
"Price": 2.5
}
但是,当我这样做时,该服务确实使用我提交的ID并使用该主键返回实体URL,即使具有该密钥的实体已经存在。
当我尝试获取该网址时,响应只是说Syntax Error
。当我查询整个集合时,我可以看到现在有两个实体ID=0
,一个以前存在的实体和我创建的实体。
这只是参考服务实施中的一个错误吗?或者,OData真的没有规定在创建实体时让服务分配主键的(可能非常常见的)场景吗?
答案 0 :(得分:0)
在服务实现中,这是一个错误。
很可能ODataDemo.Product
尚未在ORM或基础数据库中用身份种子声明。
红色标志是,如果ID为零(或任何ID)的发布结果允许您创建具有相同ID的多行且没有引发错误,则该数据类型定义不正确。
在服务中,按预期运行(代表您的身份列),结果将是响应中的ID将是基础数据库表的下一个增量ID,而不是您传入的ID
除非多行ID列 IS NOT 主键列,否则允许多行具有相同ID的实现不符合OData v4。选择或对单个记录进行操作的语法取决于可用于唯一引用每一行的列的存在和声明。
这是网址
中括号中的值11
.../Products(11)
所引用的列。