EFCore 5.0:释放 DbContext 时更改跟踪器(DbContext 生命周期)

EFCore 5.0: Change tracker when DbContext is disposed (DbContext lifetime)

我正在使用 EFCore 加载 'User' 实体和用户创建的相关 'Orders'。

我有一个构造函数(来自实际代码的简化示例),它使用 id=1 加载用户并执行一个命令来更新 LoadedUser 实体中的更改。但是在当前代码中,CmdApply 显然是错误的:

public User LoadedUser { get; set; }

public MyViewModel
{
  LoadedUser = loadUser(1);
  
  CmdApply = new ActionCommand(p =>
  {
    using (var db = new MyDbContext())
    {
      try
      {
        // Save changes into database
        db.SaveChanges();
      }
      catch (Exception e)
      {
        UiTools.StatusBar.AddNotification($"Failed to update user in database: {e.InnerException.Message}");
      }
  }, p => true)); // TODO Instead 'true' check for changes in LoadedUser
}

loadUser() 方法如下:

private User loadUser(int id)
{
  using (var db = new MyDbContext())
  {
    // Load the user completely with all its navigation properties
    var loadedUser = db.Users
      .Include(s => s.Orders)
      .SingleOrDefault(s => s.Id == id);
      
    return loadedUser;
  }
}

因此,在构造函数中调用 loadUser() 后,MyDbContext 将在剩下的 using 块中处理。现在,当调用 CmdApply 时,用户不会被保存,因为它与 DbContext 分离,因为使用块导致 DbContext 的生命周期很短。

当然,我可以在构造函数中创建 DbContext,然后只要视图模型存在,它就会存在。但正如我在文档中读到的那样,DbContexts 应该存在的时间越短越好。遇到这种情况怎么办?

我觉得可以这样解决:

  1. 加载你的用户,处理 DBContext
  2. 将您的用户模型保存在某处
  3. 保存时创建新的 DBContext
  4. 在新环境中更新您的模型。
  5. 致电db.SaveChanges()

看这里:DbContext.Update on MSDN