实体框架数据库初始化: 在初始化新的Azure SqlDatabase时出现超时问题

5

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

我使用Entity Framework Code First来创建/初始化新数据库。代码如下:

// 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方法中,上面的代码也失败了。

你能分享一下你看到的实际异常和完整的错误信息吗?谢谢! - Torsten Grabs
我已经添加了异常处理。谢谢。 - mmmato
你的迁移配置类中还有一个 CommandTimeout 属性,请尝试设置它。https://msdn.microsoft.com/zh-cn/library/system.data.entity.migrations.dbmigrationsconfiguration.commandtimeout(v=vs.113).aspx - Rowan Miller
哇,终于搞定了!非常感谢米勒先生给的提示!很遗憾 Azure 开发支持团队没能指引我找到这个解决方案。再次感谢您! - mmmato
2个回答

7

当使用Code First Migrations进行数据库初始化过程时,似乎还涉及另一个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.cs 类:

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;
    }
}

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

谢谢您的提示,但不幸的是这并没有改变任何事情。我的 ConnectionString 已经使用了连接超时:Server=XXX.database.windows.net;Database=DB_Customer_34;User Id=XXX;Password=XXX;Connection Timeout=240;MultipleActiveResultSets=True;Encrypt=True;App=EntityFramework。 - mmmato

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接