“更新数据库”命令因超时异常而失败

Posted

技术标签:

【中文标题】“更新数据库”命令因超时异常而失败【英文标题】:"Update-Database" command fails with TimeOut exception 【发布时间】:2015-11-26 15:08:03 【问题描述】:

我正在使用 EF 迁移并且有一个包含大量数据的表。我需要更改混凝土柱的 MaxLength(它没有长度限制)。

ALTER TABLE MyDb ALTER COLUMN [MyColumn] [nvarchar](2) NULL

并且此命令因 TimeOut 异常而失败。 尝试在 nDbContext 构造函数中设置 CommandTimeout 没有任何运气。

是否有任何方法可以禁用或设置包管理器控制台 EF 命令的超时?

【问题讨论】:

【参考方案1】:

自己找到了解决办法。

从 EF5 开始,有一个新属性 CommandTimeout 可从 DbMigrationsConfiguration

获得
internal sealed class MyMigrationConfiguration : DbMigrationsConfiguration<MyDbContext>

    public Configuration()
    
        CommandTimeout = 10000; // migration timeout
    

【讨论】:

在该示例中调用 Configuration 方法的内容是什么?还是应该是构造函数方法(在示例中它无意中与类名不匹配)? 试试这个:msdn.microsoft.com/en-us/data/jj591621.aspx#initializer 或这个:entityframeworktutorial.net/code-first/… 只是附注:值 0 表示没有限制(尝试执行命令将无限期地等待)。 (msdn.microsoft.com/en-us/library/…)【参考方案2】:

也可以使用脚本编写出更改

Update-Database -script

然后您可以获取脚本并使用 SQL Management Studio 对数据库运行它。

【讨论】:

感谢您的提示!我没想到你能做到这一点。 :-) 脚本在哪里生成?我试过这个,但没有得到脚本。它是否将其作为文件保存在某个地方? 嘿,我已经有一段时间没有使用这个了,但我很确定它已经将它转储到控制台中了? 在 VS 2017 中,它使用 sql 命令打开了一个新文件,很棒的提示。 对于那些好奇的人来说,迁移在技术上也是applied。不需要进一步的操作,因此您需要确保 SQL 被实际执行 - 如果您不执行 SQL EF 将愉快地继续执行,就像您执行了一样【参考方案3】:

我遇到了几乎完全相同的事情:尝试增加列长度时超时。对我来说,一个小时前使用update-database 就可以了。问题原来是我试图改变的数据库和表上的一个开放事务。一旦我回滚了那个事务,update-database 命令就顺利通过了。

【讨论】:

【参考方案4】:

在我的情况下,问题是由一个非常大的查询引起的,该查询在 EF 中超时但能够在 SSMS 中完成。

建议Update-Database -script 的答案对我不起作用,它给出了另一个错误消息。

对我来说,我做了以下事情:

打开 SSMS 工具 > SQL Server Profiler 回到 VS 并运行 Update-Database 观看服务器分析器 您应该能够看到超时的查询 复制该查询并在 SSMS 中运行它 现在重新运行 Update-Database,较慢的部分应该没问题,因为查询已经完成。

免责声明:这可能不适用于所有情况,因为这取决于特定查询会减慢您的速度。对我来说,它奏效了。

【讨论】:

【参考方案5】:

例如,只需为 mysql 120sec 添加 ConnectionStrings "Command Timeout=120"

【讨论】:

【参考方案6】:

EntityFrameworkCore 遇到了同样的更新数据库命令超时问题。发现 EFCore 中不再存在 -script 参数。文档说您需要使用 Script-Migration。

EFCore Script-Migration

您指定应用于数据库的最后一次迁移,它将为之后的所有内容生成一个脚本以使其成为最新:

Script-Migration 20210307058985_addIndexesToClientTable

您可以从 .net 项目中的迁移文件名中获取完整的迁移 ID,只需将 .cs 去掉。或者,您可以从数据库中的 __EFMigrationsHistory 表中获取它。

如果你需要一个脚本来创建一个新的数据库,它说使用 0:

Script-Migration 0 InitialCreate

对我来说,它在 VS 中打开了一个临时 .sql 文件,因为我从包控制台管理器运行它,然后我能够在 MSSQL Management Studio 中复制和执行它。

21 年 8 月 20 日更新

出于某种原因,我的新迁移要求我提供可选的 -From 和 -To 开关,以便它生成脚本:

脚本迁移 - 从 20210307058985_addIndexesToClientTable - 到 20210820205751_modifyIndexesOnClientTable

【讨论】:

【参考方案7】:

@deeptowncitizen 的回答绝对是实现这一目标的简单方法。我也想提供另一种简单的方法。

如果您已设置迁移主机(例如,Update-Database 命令中的 -StartupProject。您可以按如下方式设置 DI 注册

services.AddDbContext<MarketDataContext, MarketDataContext>(opts =>
            
                opts
                    .UseSqlServer(dbConn, a => 
                        a.MigrationsAssembly("xxxxxx.Database.MarketData")
                            .CommandTimeout(10000)) //set the timeout here
                    .EnableDetailedErrors()
                    .EnableSensitiveDataLogging();
            );

这在我的情况下效果很好,因为这个上下文是 nugetized 并且我不希望消费者自动将命令超时设置为 10000。我只希望这个可笑的高超时在我的构建/发布管道期间生效

【讨论】:

以上是关于“更新数据库”命令因超时异常而失败的主要内容,如果未能解决你的问题,请参考以下文章

为啥@jdbc 查询因连接超时而失败?

Glue 作业因 Amazon S3 超时而失败

XCUI 测试因异步等待失败而失败:超过 30 秒的超时,未达到预期

ESP32 闪烁上传开始并因超时而失败

针对使用nuget命令,因下载超时安装失败的程序包,可以离线方式安装

SQL Server 错误:用户登录失败 -- 在迁移命令更新数据库 [重复]