简体   繁体   English

“Update-Database”命令因超时异常而失败

[英]"Update-Database" command fails with TimeOut exception

I'm using EF migrations and have a table with a lot of data.我正在使用 EF 迁移并且有一个包含大量数据的表。 I need to change MaxLength of a concrete column (it hadn't length constraints).我需要更改混凝土柱的 MaxLength(它没有长度限制)。

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

And this command fails with TimeOut exception.并且此命令因 TimeOut 异常而失败。 Tried to setup CommandTimeout i nDbContext constructor without any luck.试图在 nDbContext 构造函数中设置 CommandTimeout 没有任何运气。

Is there any way to disable or setup timeout for Package Manager Console EF commands?有没有办法禁用或设置包管理器控制台 EF 命令的超时?

Found solution by myself.自己找到了解决办法。

Since EF5 there is a new property CommandTimeout which is available from DbMigrationsConfiguration由于 EF5 有一个新属性CommandTimeout可从DbMigrationsConfiguration 获得

internal sealed class MyMigrationConfiguration : DbMigrationsConfiguration<MyDbContext>
{
    public Configuration()
    {
        CommandTimeout = 10000; // migration timeout
    }
}

Alternatively script out the change by using或者,使用脚本编写更改

Update-Database -script

You can then take the script and run it using SQL Management Studio against the database.然后,您可以获取脚本并使用 SQL Management Studio 针对数据库运行它。

I just had almost the exact same thing: timeout expired when trying to increase a column length.我刚刚遇到了几乎完全相同的事情:尝试增加列长度时超时已过期。 For me, using update-database had been working just fine an hour ago.对我来说,一个小时前使用update-database一直很好。 The problem turned out to be an open transaction on the database and table I was trying to alter.问题原来是我试图改变的数据库和表上的一个开放事务。 Once I rolled back that transaction, the update-database command went through without problems.一旦我回滚了那个事务, update-database命令就顺利通过了。

Ran into this same Update-Database command timeout issue with EntityFrameworkCore.使用 EntityFrameworkCore 遇到同样的更新数据库命令超时问题。 Found that the -script argument no longer exists in EFCore.发现 EFCore 中不再存在 -script 参数。 Documentation says you need to use Script-Migration.文档说你需要使用 Script-Migration。

EFCore Script-Migration EFCore 脚本迁移

You specify the last migration that was applied to your database and it will generate a script for everything after it to get it current:您指定应用于数据库的最后一次迁移,它将为之后的所有内容生成一个脚本以使其成为最新:

Script-Migration 20210307058985_addIndexesToClientTable

You can get the full migration id from your migration file names in your .net project, just take the .cs off the end.您可以从 .net 项目中的迁移文件名中获取完整的迁移 ID,只需将 .cs 去掉即可。 Alternatively, you can get it from your __EFMigrationsHistory table in your database.或者,您可以从数据库中的 __EFMigrationsHistory 表中获取它。

If you need a script for creating a new DB it says to use 0:如果您需要一个用于创建新数据库的脚本,它会说使用 0:

Script-Migration 0 InitialCreate

For me it opened a temp .sql file in VS since I ran it from the package console manager and I was able to then copy and execute it in MSSQL Management Studio.对我来说,它在 VS 中打开了一个临时 .sql 文件,因为我从包控制台管理器运行它,然后我能够在 MSSQL Management Studio 中复制和执行它。

8/20/21 Update 8/20/21 更新

for some reason my new migrations are requiring me to provide the optional -From and -To switches in order for it to generate a script:出于某种原因,我的新迁移要求我提供可选的 -From 和 -To 开关,以便生成脚本:

Script-Migration -From 20210307058985_addIndexesToClientTable -To 20210820205751_modifyIndexesOnClientTable脚本迁移 - 从 20210307058985_addIndexesToClientTable - 到 20210820205751_modifyIndexesOnClientTable

In my case the issue was caused by a very large query which timed out in EF but was able to complete in SSMS.在我的情况下,问题是由一个非常大的查询引起的,该查询在 EF 中超时但能够在 SSMS 中完成。

The answer which suggests Update-Database -script did not work for me, it gave another error message.建议Update-Database -script的答案对我不起作用,它给出了另一条错误消息。

For me, I did the following:对我来说,我做了以下事情:

  • Open SSMS打开 SSMS
  • Tools > SQL Server Profiler工具 > SQL Server Profiler
  • Go back to VS and run Update-Database返回 VS 并运行 Update-Database
  • Watch the Server Profiler观看服务器分析器
  • You should be able to see the query it times out on您应该能够看到它超时的查询
  • Copy that query and run it in SSMS复制该查询并在 SSMS 中运行它
  • Now re-run Update-Database and that slower part should be fine because the query has already been completed.现在重新运行 Update-Database 并且较慢的部分应该没问题,因为查询已经完成。

Disclaimer: This might not work for all cases, because it depends on what particular query is slowing you down.免责声明:这可能不适用于所有情况,因为这取决于哪个特定查询会减慢您的速度。 For me, it worked.对我来说,它奏效了。

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

@deeptowncitizen's answer is definitely an easy way to accomplish this. @deeptowncitizen 的回答绝对是实现这一目标的简单方法。 I wanted to offer another simple way as well.我也想提供另一种简单的方法。

If you have your migration host setup (EG what is known as the -StartupProject in the Update-Database command. You can setup your DI registration as follows如果您有迁移主机设置(例如,在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();
            });

This works great in my situation because this context is nugetized and I don't want consumers to automatically have a command timeout of 10000. I only want this ridiculously high timeout to take effect during my build / release pipeline这在我的情况下效果很好,因为这个上下文是 nugetized,我不希望消费者自动将命令超时设置为 10000。我只希望这个高得离谱的超时在我的构建/发布管道期间生效

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM