Web API和RavenDB-在插入实体之前,检查实体是否已经存在

本文关键字:实体 检查 是否 存在 API RavenDB- 插入 Web | 更新日期: 2023-09-27 17:58:38

我有一个PUT API端点,我想在更新和存储之前检查具有指定ID的记录是否已经存在。

来自EntityFramework/SQLServer世界的我发现奇怪的是,尝试更新不存在的记录只会创建一个具有错误ID的新文档,而不是抛出异常。

以下是我的控制器端点和回购方法的代码:

 public Models.Widget Put(Models.Widget entity)
    {
        using (_unitOfWork)
        {
            var originalWidget = _widgetRepository.Get(entity.Id);
            if(null == originalWidget)
             throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NotFound, string.Format("Widget with id of {0} could not be found.", entity.Id)));
            _widgetRepository.Store(entity);
            _unitOfWork.SaveChanges();
            return entity;
        }
    }

回购方式:

 public Widget Get(long id)
    {
        var widget = Session.Load<Widget>("widgets/"+id);
        return widget;
    }
 public void Store(Widget model)
    {
        Session.Store(model);
    }

假设我们通过了控制器中的空检查,我得到的错误如下:

Message: "An error has occurred."
ExceptionMessage: "Attempted to associate a different object with id 'Widgets/33'."

我知道为什么我得到错误,我最终"跟踪"了两个具有相同id的实体。

我有两种可能的解决方案,希望您能提供反馈。

  1. 找到一种有效的方法,通过不加载原始文件进行跟踪的ID来检查是否存在
  2. 获取原始文件并将其与传入的PUT DTO一起"修补",然后将其存储回数据库中

你们觉得怎么样?

Web API和RavenDB-在插入实体之前,检查实体是否已经存在

Raven的Store方法类似于SQL Server中的INSERT。没有UPDATE,您只需从数据库加载对象(将其置于更改跟踪之下),对其进行更改,然后调用SaveChanges。

告诉Raven"这是我通过HTTP获得的这个对象,请用这些内容更新这个文档id"不是一个好主意,因为这样你就放弃了Raven的电子标签,它可以控制并发性。

根据您的情况,最好通过WebAPI将您的Raven模型直接发送给客户,然后直接取回。无论您是否使用完全相同的类或单独的DTO类型类与客户端通信,都可以使用AutoMapper将通过WebAPI传入的对象的属性映射到从数据库加载的RavenDB模型。

尝试使用乐观并发。通过这种方式,你可以检测你是否在写一个id已经在使用的文档:

session.Advanced.UseOptimisticConcurrency = true;