带字节[]的C#Odata WebApi并发

带字节[]的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标头,如:

我已经为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标头,如:

    [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存储库和内存存储库进行了测试