我尝试实现 Microsoft 的 API 更新案例,如下所示。 首先我从数据库中获取记录以确定它是否为空。如果没有,将触发更新。 在代码中
efCore
会抛出 DBConcurrencyException
,因为该元素已被跟踪。
有什么问题吗?
// PUT api/contactsconvention/{guid}
[HttpPut("{id}")]
[ApiConventionMethod(typeof(DefaultApiConventions),
nameof(DefaultApiConventions.Put))]
public IActionResult Update(string id, Contact contact)
{
// First tracking in my code
var contactToUpdate = _contacts.Get(id);
if (contactToUpdate == null)
{
return NotFound();
}
// Second tracking in my code -> Exception at dbContext.SaveChanges()
_contacts.Update(contact);
return NoContent();
}
.Get方法后面必须是非chagen-tracking方法。所以我添加了它,现在它可以工作了。
// PUT api/contactsconvention/{guid}
[HttpPut("{id}")]
[ApiConventionMethod(typeof(DefaultApiConventions),
nameof(DefaultApiConventions.Put))]
public IActionResult Update(string id, Contact contact)
{
// First tracking in my code
var contactToUpdate = _contacts.GetAsNoTracking(id);
if (contactToUpdate == null)
{
return NotFound();
}
// Second tracking in my code -> Exception at dbContext.SaveChanges()
_contacts.Update(contact);
return NoContent();
}
// Non-tracking repository method:
return context.Contacts.AsNoTracking().Single(s => s.Id == id);
我的单元测试也有一个问题,它使用模拟的 dbSet。 AddRange 方法还添加 ChangeTracking 值。可以使用以下代码删除这些内容,如本post中所述。
foreach (var entity in InMemoryScheduleDbContext.ChangeTracker.Entries())
{
entity.State = EntityState.Detached;
}