如何在不处理上下文的情况下刷新实体框架连接?

本文关键字:实体 刷新 框架 连接 情况下 处理 上下文 | 更新日期: 2023-09-27 18:18:36

在我们的应用程序中使用实体框架几年没有问题之后,我们公司开始为我们的用户部署笔记本电脑。这些笔记本电脑将在现场使用,并与我们的网络直接有线连接。

从那以后,我们看到程序中崩溃的数量大幅增加,异常日志显示
System.Data.SqlClient.SqlException: A transport-level error has occurred when receiving results from the server. 
(provider: Session Provider, error: 19 - Physical connection is not usable)

我的理论是,问题的根源在于笔记本电脑不像个人电脑那样会进入睡眠状态。我认为网络适配器在笔记本电脑进入睡眠状态时被禁用,当它重新醒来时被重新启用。我认为我们的程序仍在尝试使用一个不再存在的连接与服务器通信。

所以,我的想法是回应:

Microsoft.Win32.SystemEvents.PowerModeChanged

我可以检测它何时唤醒并刷新连接。问题是,我似乎可以做到这一点的唯一方法是处置当前的DbContext并实例化一个新的。

这样做的问题是任何未提交的更改都会丢失。如果用户一整天都在更新记录,他们就会丢失工作。不仅如此,我们还需要遍历所有的应用程序,所有的视图模型并结合一些退出编辑模式的通知给用户。一点也不好看。

我的第二个想法是创建一个方法来克隆DbContext。当计算机唤醒时,我可以创建一个新的DbContext,并在处理它之前从旧的DbContext中复制状态…但是我们的一些数据模型非常庞大,为每个模型创建一个深度克隆方法将是一项相当艰巨的任务。

我突然想到,这可能仍然是我们必须走的路。但如果我不去检查是否有人知道一种方法来刷新实体框架DbContext的连接而不失去它的当前状态,那我就太愚蠢了。

如何在不处理上下文的情况下刷新实体框架连接?

如果有人给我提建议,我将不胜感激。

我不确定,它是否会对您的具体情况有所帮助,但您可以检查DbConetxt类使用的连接状态,并最终重新打开它。

if(context.Database.Connection.State == ConnectionState.Closed) {
    context.Database.Connection.Open();
}

如果可以在DbContext的构造函数中传递一个连接并手动管理该连接,

var conn = new SqlConnection("{connectionString}"));
var context =  new DbContext(conn, contextOwnsConnection: false);
...
if(conn.State == ConnectionState.Closed) {
    conn.Open(); 
}
context.SaveChanges(); 
...
context.Dispose();
conn.Dispose();

如果您想在EF 5或更早的版本中使用此代码,则有一些限制。

我只是想评论,但我没有足够的信誉点做到这一点,所以无论如何,我想知道是否不可能在断开连接的状态下工作与实体框架?也许下面链接中的文章能帮到你:

https://msdn.microsoft.com/en-us/data/jj592676.aspx