如何设置Entity Framework Core迁移超时?

时间:2016-08-17 21:54:23

标签: c# entity-framework entity-framework-core

我正在使用EF Core的最新版本(1.0.0)。我有一个迁移到一个相当大的数据库上运行。

我跑:

  

dotnet ef数据库更新-c ApplicationDbContext

得到:

  

超时已过期。完成之前已经过了超时时间   操作或服务器没有响应。

在连接字符串中,我明确地设置了超时:

  

连接超时= 150000

不幸的是,它没有任何帮助。我该怎么做?

4 个答案:

答案 0 :(得分:29)

您收到的错误消息是命令超时,而不是连接超时。

<强>更新

正如Pace在评论中所提到的,自从EF Core 2.0以来,您可以使用IDesignTimeDbContextFactory来更改上下文在设计时通过工具创建的行为,例如迁移时发生的情况。

在项目中创建一个实现IDesignTimeDbContextFactory接口的单独类,并使用DbContextoptionsBuilder配置所需的行为 - 在这种情况下,将命令超时值设置为600秒:

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;

namespace EFCoreSample.Model
{
    public class SampleContextFactory : IDesignTimeDbContextFactory<SampleContext>
    {
        public SampleContext CreateDbContext(string[] args)
        {
            var optionsBuilder = new DbContextOptionsBuilder<SampleContext>();
            optionsBuilder.UseSqlServer(@"Server=.\;Database=db;Trusted_Connection=True;", opts => opts.CommandTimeout((int)TimeSpan.FromMinutes(10).TotalSeconds));

            return new SampleContext(optionsBuilder.Options);
        }
    }
}

确保您现有的DbContext有一个构造函数,该构造函数将DbContextOptions个对象作为参数:

public AdventureContext(DbContextOptions options) : base(options){}

当工具运行迁移时,它首先查找实现IDesignTimeDbContextFactory的类,如果找到,将使用它来配置上下文。运行时行为不受影响。

原来的答案不再适用

使用EF命令时无法在上下文中设置CommandTimeout。但是你可以在构造函数中全局设置它,如果你不需要保留它,可以在以后删除它:

public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext()
    {
        Database.SetCommandTimeout(150000);
    }
}

<击>

答案 1 :(得分:7)

您只能通过在调用Migrations方法之前在上下文中设置超时来设置迁移超时:

using (var context = new DispatchingDbContext(_configuration))
{
    context.Database.SetCommandTimeout(300);
    await context.Database.MigrateAsync().ConfigureAwait(false);
}

Set timeout for migrations ef .netcore

答案 2 :(得分:4)

使用Entity Framework 6,我使用DbMigrationsConfiguration.CommandTimeout属性为迁移设置了更长的超时。

像这样:

在我的Global.asax.cs中:

protected void Application_Start()
{
    DatabaseMigrationConfig.Register();
    //etc
}

我的DatabaseMigrationConfig班级:

public class DatabaseMigrationConfig
{
    internal static void Register()
    {
        using (var context = new MyContext(Config.ConnectionStringMigrations))
        {
            Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext,
                                        Migrations.Configuration>());
            context.Database.Initialize(false);
        }
    }
}

我的Migrations.Configuration课程:

using System.Data.Entity.Migrations;

internal sealed class Configuration : DbMigrationsConfiguration<MyContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
        AutomaticMigrationDataLossAllowed = false;
        CommandTimeout = 360;// <----- 6 minute timeout!
    }
}

参考文献:

Migrations: timeout error in Update-Database commands DbMigrationsConfiguration.CommandTimeout Property

请注意,我还在迁移期间使用不同的连接字符串 - 用户具有比网站更高的权限,并且连接超时更长。请参阅此问题 - How to use a different connection string (but same database) for migrations

答案 3 :(得分:1)

您也可以在数据库上下文类的构造函数中做到这一点。

public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
    : base(options)
{
    Database.SetCommandTimeout(150000);
}