我目前有一个这样的对象(简化):
public class Image {
public int Id { get; set; }
public int ExternalId { get; set; }
}
现在假设我有这个方法(主要是伪代码):
public void GetImage(int externalId) {
var existingImage = db.Images.FirstOrDefault(i => i.ExternalId == externalId);
if (existingImage != null) {
return existingImage;
}
var newImage = new Image() { ExternalId = externalId };
db.Images.Attach(newImage);
db.SaveChanges();
return newImage;
}
因为 ExternalId 不是键,所以更改跟踪器不会关心跟踪器中是否有“重复”图像。
所以现在,假设这个方法被调用了两次,同时通过 AJAX 和 Web API(我当前的场景)。它是异步的,所以现在有两个线程调用这个方法。
如果调用之间的时间足够短(在我的情况下是这样),则会将两行添加到具有相同外部 ID 的数据库中,因为现有的检查都不会返回一行。我已经大大简化了这个示例,因为在我的真实示例中,当我从服务中获取“图像”时存在时间问题。
我怎样才能防止这种情况?无论图像是新的还是更新的,我都需要返回图像。我在数据库中添加了一个唯一约束,所以我得到了一个异常,但是在客户端上,调用失败了,而它应该使用现有的图像而不是抛出异常。
如果我正确理解 EF,我可以通过创建ExternalId
一个主键然后使用并发来处理这个问题,对吧?有什么方法可以避免更改我当前的模型,还是这是唯一的选择?