【发布时间】:2021-08-26 16:44:19
【问题描述】:
我正在使用 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() 时,我得到以下异常:预计读取 4 个标头字节,但只收到 0 个。 em>(请参阅下面的完整堆栈跟踪)
我不知道为什么我会遇到这样的异常,如果我取 1000000 行,但如果我只取 750000 则不会。 我读到它可能与 SQL 服务器的超时有关:下面列出,但我真的不知道它是否真的与一个超时有关以及如何找到解决方案。我应该将更新分成几个并调用几次 SaveChanges() 吗?
感谢您的任何建议。
以下是 MySql 服务器的超时时间:
connect_timeout 10
delayed_insert_timeout 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 关闭
interactive_timeout 610
lock_wait_timeout 31536000
net_read_timeout 30
net_write_timeout 60
rpl_stop_slave_timeout 31536000
slave_net_timeout 60
thread_pool_idle_timeout 60
wait_timeout 610
这是完整的堆栈跟踪:
来自 Microsoft.EntityFrameworkCore.Update:错误保存上下文类型“MyDbContext”的更改时数据库中发生异常。
Microsoft.EntityFrameworkCore.DbUpdateException:更新条目时出错。有关详细信息,请参阅内部异常。
---> MySql.Data.MySqlClient.MySqlException (0x80004005): 读取结果集失败。
---> System.IO.EndOfStreamException:预期读取 4 个标头字节,但只收到 0。
在 C:\projects\mysqlconnector\src\MySqlConnector\Protocol\Serialization\ProtocolUtility.cs 中的 MySqlConnector.Protocol.Serialization.ProtocolUtility.DoReadPayloadAsync(BufferedByteReader bufferedByteReader, IByteHandler byteHandler, Func1 getNextSequenceNumber, ArraySegmentHolder1 previousPayloads, ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior):第 462 行
在 C:\projects\mysqlconnector\src\MySqlConnector\Protocol\Serialization\StandardPayloadHandler.cs:line 37
在 C:\projects\mysqlconnector\src\MySqlConnector\Core\ServerSession.cs:line 665 中的 MySqlConnector.Core.ServerSession.ReceiveReplyAsync(IOBehavior ioBehavior, CancellationToken cancelToken) 处
【问题讨论】:
-
所以,这是已知的EF的弱点。并且有很多解决方案可以通过第三方库在没有 ChangeTracker 的情况下做到这一点。
-
谢谢,但为什么会向我发送此错误?你说的弱点是什么?我搜索批量库,但它们不是免费的。正如您在以下回复中提到的,我将尝试使用 FromSqlRaw 使用直接原始语句。谢谢
-
更新问题,需要更新不同值的记录。没有那么多图书馆可以做到这一点。
-
我更新了问题,但是如果我使用 FromSqlRaw 更新 100 万条记录,我将需要调用 FromSqlRaw 100 万次,因为我无法编写单个更新 SQL 查询来更新 100 万条记录。一次具有不同值的记录,除非我需要插入 100 万条记录,因为我可以插入到单个 sql 查询中?
-
没错,将准备样本如何尽可能快地更新百万条记录。
标签: exception entity-framework-core