exception - EF Core:更新数千条记录失败
问题描述
我正在使用 EF Core 更新名为 MyTable 的表中的数千条记录。它已经有 1.500.000 行。这是我用来更新其属性之一的简单代码 MyProp 为每条记录使用不同的值:
using (MyDbContext ctx = new MyDbContext())
{
var rows = ctx.Set<MyTable>().Take(1000000).ToList(); // I only take the first 1 million rows
int idx = 0;
foreach (var row in rows)
{
row.MyProp = $"MyNewValue{idx++}";
}
ctx.SaveChanges();
}
如果我用一百万行来更新它们,在调用 ctx.SaveChanges() 时,我会得到以下异常:Expected to read 4 header bytes but only received 0.(参见下面的完整堆栈跟踪)
我不知道为什么我会遇到这样的异常,如果我取 1000000 行,但如果我只取 750000 则不会。我读到它可能与 SQL 服务器的超时有关:下面列出,但我真的不知道它是否真的与一个超时有关以及如何找到解决方案。我应该将更新分成几个并调用几次 SaveChanges() 吗?
感谢您的任何建议。
以下是来自 MySql 服务器的超时:
连接超时 10
延迟插入超时 300
have_statement_timeout 是
innodb_flush_log_at_timeout 1
innodb_lock_wait_timeout 50
innodb_print_lock_wait_timeout_info 关闭
innodb_rollback_on_timeout 关闭
交互超时 610
lock_wait_timeout 31536000
net_read_timeout 30
net_write_timeout 60
rpl_stop_slave_timeout 31536000
slave_net_timeout 60
线程池空闲超时 60
等待超时 610
这是完整的堆栈跟踪:
来自 Microsoft.EntityFrameworkCore.Update:错误保存上下文类型“MyDbContext”的更改时数据库中发生异常。Microsoft.EntityFrameworkCore.DbUpdateException:更新条目时出错。有关详细信息,请参阅内部异常。---> MySql.Data.MySqlClient.MySqlException (0x80004005): 读取结果集失败。---> System.IO.EndOfStreamException:预期读取 4 个标头字节,但仅收到 0。在 MySqlConnector.Protocol.Serialization.ProtocolUtility.DoReadPayloadAsync(BufferedByteReader bufferedByteReader, IByteHandler byteHandler, Func1 getNextSequenceNumber, ArraySegmentHolder
1 previousPayloads, ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior) 在 C:\projects\mysqlconnector\src\MySqlConnector\Protocol\Serialization\ProtocolUtility.cs:第 462 行在 MySqlConnector.Protocol.Serialization.StandardPayloadHandler.ReadPayloadAsync(ArraySegmentHolder`1 缓存, ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior) 在 C:\projects\mysqlconnector\src\MySqlConnector\Protocol\Serialization\StandardPayloadHandler.cs:第 37 行,在 C:\projects\mysqlconnector\src\ 中的 MySqlConnector.Core.ServerSession.ReceiveReplyAsync(IOBehavior ioBehavior, CancellationToken cancelToken) MySqlConnector\Core\ServerSession.cs:第 665 行
解决方案
对于您的用例,因为您想设置一个显式值,您可以执行一些不会在服务器上返回任何行的直接 sql。
阅读这个精彩的章节,您实际上可以将整个操作转换为仅在 db 上运行的简单 sql 语句。分页(跳过)部分将被移动到数据库中,不会检索任何数据以节省性能并且整个操作不会消耗服务器上的内存
推荐阅读
- c# - 并行访问文件
- hive - 在 Hive 中将列名转换为行
- javascript - 如何在 NetSuite 上查找销售订单中的相关记录?
- java - 使用新对象创建对象{}
- python - 我将如何构建自己的评估指标,以最大限度地减少使用 XGBoost 的高度不平衡类的测试错误?
- odata - 是否可以将记录添加到 oData 模型,以便在 UI 上可见且无需发布?
- javascript - 从 URL 中删除查询
- python - 第二次执行代码时spyder没有响应
- odoo-12 - 停止 longpolling cron 调用以轻松调试
- .net - .NET 到 Docker Hub 构建成功但发布失败