【问题标题】:"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 命令的超时?

【问题讨论】:

    标签: c# entity-framework timeout entity-framework-6


    【解决方案1】:

    自己找到了解决办法。

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

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

    【讨论】:

    【解决方案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。我只希望这个可笑的高超时在我的构建/发布管道期间生效

            【讨论】:

              猜你喜欢
              • 2021-05-25
              • 1970-01-01
              • 1970-01-01
              • 2023-04-02
              • 1970-01-01
              • 2017-06-23
              • 2020-05-09
              • 2018-06-27
              • 1970-01-01
              相关资源
              最近更新 更多