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的实体。
我有两种可能的解决方案,希望您能提供反馈。
- 找到一种有效的方法,通过不加载原始文件进行跟踪的ID来检查是否存在
- 获取原始文件并将其与传入的PUT DTO一起"修补",然后将其存储回数据库中
你们觉得怎么样?
告诉Raven"这是我通过HTTP获得的这个对象,请用这些内容更新这个文档id"不是一个好主意,因为这样你就放弃了Raven的电子标签,它可以控制并发性。
根据您的情况,最好通过WebAPI将您的Raven模型直接发送给客户,然后直接取回。无论您是否使用完全相同的类或单独的DTO类型类与客户端通信,都可以使用AutoMapper将通过WebAPI传入的对象的属性映射到从数据库加载的RavenDB模型。
尝试使用乐观并发。通过这种方式,你可以检测你是否在写一个id已经在使用的文档:
session.Advanced.UseOptimisticConcurrency = true;