带字节[]的C#Odata WebApi并发
我已经为ODataV4设置了一个WebApi端点。我没有直接使用实体框架,而是定义了一些POCO带字节[]的C#Odata WebApi并发,c#,asp.net-web-api,odata,C#,Asp.net Web Api,Odata,我已经为ODataV4设置了一个WebApi端点。我没有直接使用实体框架,而是定义了一些POCO public class ServiceDTO { public string Id { get; set; } public string Name { get; set; } [Timestamp] public byte[] RowVersion { get; set; } } 我的问题是Odata控制器的补丁方法,我将检查If Match标头,如:
public class ServiceDTO
{
public string Id { get; set; }
public string Name { get; set; }
[Timestamp]
public byte[] RowVersion { get; set; }
}
我的问题是Odata控制器的补丁方法,我将检查If Match标头,如:
[AcceptVerbs("PATCH", "MERGE")]
public async Task<IHttpActionResult> Patch([FromODataUri] string key, Delta<ServiceDTO> patch, ODataQueryOptions<ServiceDTO> options)
{
if (patch == null)
{
var responseMessage = new HttpResponseMessage();
responseMessage.StatusCode = HttpStatusCode.ExpectationFailed;
responseMessage.Content = new StringContent("Missing properties");
return ResponseMessage(responseMessage);
}
Validate(patch.GetEntity());
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (options.IfMatch != null)
{
var result = this.repository.Get(options).AsQueryable().Where(u => u.Id == key);
if (!result.Any())
{
// The entity doesn't exist on the database and as the request contains an If-Match header we don't
// insert the entity instead (No UPSERT behavior if the If-Match header is present).
return NotFound();
}
else if (!((IQueryable<ServiceDTO>)options.IfMatch.ApplyTo(result)).Any())
{
// The ETag of the entity doesn't match the value sent on the If-Match header, so the entity has
// been modified by a third party between the entity retrieval and update..
return StatusCode(HttpStatusCode.PreconditionFailed);
}
else
{
// The entity exists in the database and the ETag of the entity matches the value on the If-Match
// header, so we update the entity.
var service = await this.repository.Get(key);
patch.Patch(service);
await this.repository.Update(service);
if (service == null)
return BadRequest();
return Ok(service);
}
}
else
{
var responseMessage = new HttpResponseMessage();
responseMessage.StatusCode = (HttpStatusCode)428;
return ResponseMessage(responseMessage);
}
}
[AcceptVerbs(“补丁”、“合并”)]
公共异步任务修补程序([FromODataUri]字符串键、增量修补程序、ODataQueryOptions选项)
{
if(patch==null)
{
var responseMessage=新的HttpResponseMessage();
responseMessage.StatusCode=HttpStatusCode.ExpectationFailed;
responseMessage.Content=新的StringContent(“缺少属性”);
返回响应消息(ResponseMessage);
}
验证(patch.GetEntity());
如果(!ModelState.IsValid)
{
返回请求(ModelState);
}
if(options.IfMatch!=null)
{
var result=this.repository.Get(options).AsQueryable()。其中(u=>u.Id==key);
如果(!result.Any())
{
//该实体在数据库中不存在,并且由于请求包含If-Match头,因此我们不存在该实体
//改为插入实体(如果存在if-Match标头,则不存在向上插入行为)。
返回NotFound();
}
else if(!((IQueryable)options.IfMatch.ApplyTo(result)).Any())
{
//实体的ETag与If match标头上发送的值不匹配,因此该实体具有
//在实体检索和更新之间被第三方修改。。
返回状态码(HttpStatusCode.PremissionFailed);
}
其他的
{
//该实体存在于数据库中,并且该实体的ETag与If Match上的值匹配
//头,所以我们更新实体。
var service=wait this.repository.Get(key);
补丁(服务);
等待这个.repository.Update(服务);
if(服务==null)
返回请求();
返回Ok(服务);
}
}
其他的
{
var responseMessage=新的HttpResponseMessage();
responseMessage.StatusCode=(HttpStatusCode)428;
返回响应消息(ResponseMessage);
}
}
在POCO i中使用字节[]总是以前置条件失败而告终。当我将数据类型从byte[]替换为string或int64时,一切正常
我还尝试将DataAnnotation从[Timestamp]替换为[ConcurrencyCheck],但没有效果
我们以前在另一个使用byte的项目中使用过这段代码,但我们直接使用EF
存储库在运行时解析,它可以是一个与EF一起工作的存储库,也可以是另一个与不同后端一起工作的自定义存储库
我使用EF存储库和内存存储库进行了测试