当发生 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 条记录和链接记录播种一个数据库,以获得负载测试的想法,所以我没有为所有可能性编程,我只是希望能够处理断开连接并在可能的情况下重新连接。
谢谢
我将评论移至答案。这是我的建议,不知道你在do lots of stuff
做什么.
通常,使用 EF,您希望在 using 块中花费尽可能少的时间。转述自此 EF 教程(以及其他教程(:
- 从数据库获取现有对象。
- 在上下文范围之外更改对象名称(断开连接模式(
- 将修改后的实体传递到方法中以获取其 DBEntityEntry 对象,然后将其状态标记为"已修改">
- 调用 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();
}
}