Entity Framework 数据库初始化:初始化新的 Azure SqlDatabase 时超时

Entity Framework Database Initialization: Timeout when initializing new Azure SqlDatabase

我有一个 ASP.NET MVC 应用程序。当通过 CustomerController 创建新客户时,我 运行 一个新的后台任务(使用 HostingEnvironment.QueueBackgroundWorkItem)创建一个新的该客户的 Azure SqlDatabase。

我使用 Entity Framework Code First create/initialize 新数据库。这是代码:

// My ConnectionString
var con = "...";

// Initialization strategy: create db and execute all Migrations
// MyConfiguration is just a DbMigrationsConfiguration with AutomaticMigrationsEnabled = true
Database.SetInitializer(strategy: new MigrateDatabaseToLatestVersion<CustomerDataContext, MyConfiguration>(useSuppliedContext: true));

using (var context = new CustomerDataContext(con))
{
    // Neither 'Connection Timeout=300' in ConnectionString nor this line helps -> TimeoutException will rise after 30-40s
    context.Database.CommandTimeout = 300;

    // create the db - this lines throws the exception after ~40s
    context.Database.Initialize(true);
}

我的问题是我总是在大约 40 秒后得到 TimeoutException。我认为发生这种情况是因为 Azure 无法在这么短的时间内初始化新数据库。不要误会我的意思:Azure 会很好地创建数据库,但我想等待那一刻/摆脱 TimeoutException.

编辑1: 我在我的 ConnectionString 中使用 Connection Timeout=300 但我的应用程序并不关心它;大约 40 秒后,我总是 运行 遇到 SqlError。

编辑2: 引发的异常是 SqlException消息:超时已过。在操作完成之前超时期限已过,或者服务器没有响应。 来源:.Net SqlClient 数据提供程序

编辑3: 我现在可以确定这与ASP.NET/IIS无关。即使在简单的 UnitTest 方法中,上面的代码也会失败。

命令超时和连接超时是两种不同的设置。在这种情况下,您只需增加命令超时。您可以在 web.config: Connection Timeout=120 中增加连接超时。您唯一想要增加连接超时的时间是在创建数据库时。

使用 Code First 迁移时,似乎还有另一个 CommandTimeout 设置涉及数据库初始化过程。我想在这里分享我的解决方案,以防万一有人遇到这个问题。

感谢 Rowan Miller 为我指出解决方案的提示。

这是我的代码:

// Initialisation strategy
Database.SetInitializer(strategy: new CreateDatabaseIfNotExists<MyDataContext>());

// Use DbContext
using (var context = new MyDataContext(myConnectionString))
{
    // Setting the CommandTimeout here does not prevent the database
    // initialization process from raising a TimeoutException when using
    // Code First Migrations so I think it's not needed here.
    //context.Database.CommandTimeout = 300;

    // this will create the database if it does not exist
    context.Database.Initialize(force: false);
}

还有我的Configuration.csclass:

public sealed class Configuration : DbMigrationsConfiguration<MyDataContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
        AutomaticMigrationDataLossAllowed = false;

        // Very important! Gives me enough time to wait for Azure
        // to initialize (Create -> Migrate -> Seed) the database.
        // Usually Azure needs 1-2 minutes so the default value of
        // 30 seconds is not big enough!
        CommandTimeout = 300;
    }
}