我正在 Blazor 中构建一个习惯跟踪应用程序,使用 ASP.NET Core 6 Web API 作为后端,该应用程序使用实体框架。我有一个
Habit
实体,它拥有许多这样的实现实体:
modelBuilder.Entity<Habit>().OwnsMany(h => h.Implementations);
我正在尝试为已有实现的习惯添加一个实现。这是我的控制器操作方法中的代码:
public async Task<IActionResult> AddHabitReview([FromBody] HabitReviewModel model)
{
try
{
var habit = await _context.Habits.FindAsync(model.Id);
if (habit == null)
return NotFound("No habit found");
habit.AddImplementation(/*implementation parameters*/);
_context.Habits.Update(habit);
await _context.SaveChangesAsync();
return Ok();
}
catch (Exception ex)
{
var message = ex.Message;
return BadRequest(message);
}
}
但是我遇到以下异常:
数据库操作预计影响1行,实际影响0行;自加载实体以来,数据可能已被修改或删除。有关理解和处理乐观并发异常的信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=527962。
我还通过 SQL Server Profiler 检查了数据库查询。由于某种原因,它正在为
UPDATE
表创建 Implementation
命令,并将 Id
作为我的新实现 ID。我希望它能为实现表生成一个 CREATE 命令,因为我正在创建一个新的实现并将其附加到习惯实体。
有人可以指出我做错了什么吗?
错误的根源在于 EF Core 尝试更新 Habit 实体,但没有正确处理 Implemention 集合的更改。
所以正确的用法如下:
var habit = await _context.Habits.FindAsync(model.Id);
if (habit == null)
return NotFound("No habit found");
// create new obj
var newImplementation = new Implementation(...);
// Add new Implementation instance in `habit.Implementations`
habit.Implementations.Add(newImplementation);
// Since we have add new Implementation instance into the Habit collection
// So no need to explicitly call the Update method
await _context.SaveChangesAsync();
return Ok();