这是关于DBContext的生命周期的文档:
使用Windows Presentation Foundation(WPF)或Windows时 表单,使用每个表单的上下文实例。这可以让你使用 上下文提供的更改跟踪功能。
我已经读过DBContext
的生命周期应该尽可能短,但显然是WinForms
(我正在使用),这个规则不适用,推荐别的东西。
当前设置
此外,我的应用程序遵循MVC
模式,在我的控制器中,我已初始化DBContext
。现在,当窗体关闭时,控制器实例也被置于其中,这就是上下文死亡的地方。如果重要的话,我也在使用Database First方法。
现在总是打开一个上下文(每个表单)似乎它有自己的便利(你可以轻松跟踪上下文的变化),但是,例如,我发现自己(作为一个EF
初学者)疑惑......看看这种情况:
我有IList
个用户(用户实体)在创建表单时初始化。我运行了两个(甚至更多)我的应用程序实例,因为它适用于多用户环境。现在,假设用户A和用户B都加载相同的记录(用户管理屏幕,因此他们都是管理员)......现在当事情发生时:
用户A
对某些记录进行更改(更新)
用户B
对同一记录进行更改(更新)并将其保存到数据库中
用户A
尝试保存
抛出DbUpdateConcurrencyException
......
现在这很好,我知道一个术语乐观并发,并说用户A
和B
都在更新同一行(或同一列),我会处理一个像这个(如果我遗漏了某些东西,请纠正我):
catch (DbUpdateConcurrencyException ex)
{
ex.Entries.Single().Reload();
//Here I reload UI with a new changes, and ask a user to try again
}
现在这似乎正在工作......因为我的上下文是打开的,只要我的表单是活着的,当我在ex.Entries.Single()上执行Reload()时,列表中的特定用户(记得我已经提到用户列表之前用实际数据库值刷新,所以当我重新加载视图时,用户获得当前状态。
实际问题
到目前为止一直很好......但例如在这种情况下:
用户A
删除行
用户B
尝试更新并保存更改(已删除的行)
我遇到了多个问题,而且我不知道什么是正确的处理方法。
我想,我应该更新用户列表,但不知道如何在不处理当前上下文的情况下执行此操作。这将是一个问题...如何从数据库重新加载用户列表,而不在此代码块中处理上下文:
catch (DbUpdateConcurrencyException ex)
{
// Reload the user list with navigation properties fully initialized (note that user list is what would context.korisnik.ToList() would return)
// Reload the UI
}
在这种情况下处理Optimistic Concurrency错误的正确方法是什么?