当发生 SQLException 时,如何重新连接 using 语句中的实体数据集

本文关键字:语句 using 数据集 实体 重新连接 SQLException | 更新日期: 2023-09-27 18:33:20

情况是我有一个长时间运行的方法,它正在循环数千行并进行处理和更新。 这个循环嵌套在我的 using 语句中。

问题是当我早上上班时,我看到我的连接在晚上 8 点使用 SQLException 失败,我损失了 12 小时的处理时间。 如何重新连接并继续以编程方式处理循环?

我的想法是这样的:

using (var _data = new My.EF.MyEntities())
{
    for (int i = 1; i < 17348; i++)
    {
        try
        {
          //Do lots of stuff
        }
        catch (SqlException ex)
        {
            WriteLogFile("Error at id" + i.ToString(), ex);
            i--;
            if (_data.Database.Connection.State != System.Data.ConnectionState.Open)
            {
                _data.  // What?  nothing looks useful here to reconnect
            }
        }
    }
}

这只是开发代码,不适用于任何生产或用户环境。 我所做的只是用 10'000 条记录和链接记录播种一个数据库,以获得负载测试的想法,所以我没有为所有可能性编程,我只是希望能够处理断开连接并在可能的情况下重新连接。

谢谢

当发生 SQLException 时,如何重新连接 using 语句中的实体数据集

我将评论移至答案。这是我的建议,不知道你在do lots of stuff做什么.

通常,使用 EF,您希望在 using 块中花费尽可能少的时间。转述自此 EF 教程(以及其他教程(:

  1. 从数据库获取现有对象。
  2. 在上下文范围之外更改对象名称(断开连接模式(
  3. 将修改后的实体传递到方法中以获取其 DBEntityEntry 对象,然后将其状态标记为"已修改">
  4. 调用 SaveChanges(( 方法将对象信息更新到数据库中。

using环境中花费 12+ 小时听起来需要重新设计。话虽如此,如果您修改现有实体(从内存中,可能需要一些语法调整(,这里有一个建议:

IEnumerable<EntityTypeYouveDefined> listOfEntities;
using (var _data = new My.EF.MyEntities())
{
    listOfEntities = _data.YourTableName.Where(e => e.SomeConditionOrPropertyOrWhatever);
    //Or some other search predicate to pull what you want to change.
}
foreach(var entity in listOfEntities)
{
    entity.SomeProperty = "what you want to change";
}
using (var _data = new My.EF.MyEntities())
{
    foreach(var entity in listOfEntities)
    {
        _data.Entry(entity).State = EntityState.Modified;
    }
    _data.SaveChanges();
}

如果要创建新实体,下面是一些代码:

var listOfEntities = new List<EntityTypeYouveDefined>();
for (int i = 0; i < 17348; i++)
{
    var newEntity = new EntityTypeYouveDefined();
    //Build the newEntity relationships here
    listOfEntities.Add(newEntity);
}
using (var _data = new My.EF.MyEntities())
{
    foreach (var entity in listOfEntities)
    {
        _data.Attach(newEntity)
        //You may have to set the entity state to modified here. Can't remember, I'm doing this from memory
    }
    _data.SaveChanges();
}

这将最大限度地减少您在该循环中花费的时间并更干净。此外,如果您需要重复执行此操作,请使用using之外的循环。using块为您处理与数据库的连接。无需在 app/web.config 文件中的连接字符串之外自行管理此内容。

我所知,解决此问题的一种方法是释放旧的_data对象,然后再次初始化它。

var _data = new My.EF.MyEntities();
try
{
    for (int i = 1; i < 17348; i++)
    {
        try
        {
          //Do lots of stuff
        }
        catch (SqlException ex)
        {
            WriteLogFile("Error at id" + i.ToString(), ex);
            i--;
            if (_data.Database.Connection.State != System.Data.ConnectionState.Open)
            {
                ((IDisposable)_data).Dispose();
                _data = new My.EF.MyEntities()
            }
        }
    }
}
finally
{
    if (_data != null)
    {
        ((IDisposable)_data).Dispose();
    }
}