Установка таймаута базы данных в Entity Framework

Моя команда удерживает тайм-аут. поэтому мне нужно изменить значение тайм-аута команды по умолчанию. Я нашел "myDb.Database.Connection.ConnectionTimeout", но он доступен только для чтения.

Как установить тайм-аут команды в Entity Framework 5?

Ответ 1

Попробуйте это в своем контексте:

public class MyDatabase : DbContext
{
    public MyDatabase ()
        : base(ContextHelper.CreateConnection("Connection string"), true)
    {
        ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = 180;
    }
}

Если вы хотите определить тайм-аут в строке подключения, используйте параметр Connection Timeout, как в следующей строке подключения:

<connectionStrings>

<add name="AdventureWorksEntities"
connectionString="metadata=.\AdventureWorks.csdl|.\AdventureWorks.ssdl|.\AdventureWorks.msl;
provider=System.Data.SqlClient;provider connection string='Data Source=localhost;
Initial Catalog=AdventureWorks;Integrated Security=True;Connection Timeout=60;
multipleactiveresultsets=true'" providerName="System.Data.EntityClient" />

</connectionStrings>

Источник: Как определить строку подключения

Ответ 2

Вы можете использовать DbContext.Database.CommandTimeout = 180;

Это довольно просто и не требуется никакого броска.

Ответ 3

Мой частичный контекст выглядит следующим образом:

public partial class MyContext : DbContext
{
    public MyContext (string ConnectionString)
        : base(ConnectionString)
    {
        this.SetCommandTimeOut(300);
    }

    public void SetCommandTimeOut(int Timeout)
    {
        var objectContext = (this as IObjectContextAdapter).ObjectContext;
        objectContext.CommandTimeout = Timeout;
    }
}

Я оставил SetCommandTimeOut общедоступным, поэтому только подпрограммы, в которых мне нужно занять много времени (более 5 минут), я изменяю вместо глобального таймаута.

Ответ 4

Я продлил ответ Ронни с быстрой реализацией, поэтому вы можете использовать его так:

dm.Context.SetCommandTimeout(120).Database.SqlQuery...

public static class EF
{
    public static DbContext SetCommandTimeout(this DbContext db, TimeSpan? timeout)
    {
        ((IObjectContextAdapter)db).ObjectContext.CommandTimeout = timeout.HasValue ? (int?) timeout.Value.TotalSeconds : null;

        return db;
    }

    public static DbContext SetCommandTimeout(this DbContext db, int seconds)
    {
        return db.SetCommandTimeout(TimeSpan.FromSeconds(seconds));
    } 
}

Ответ 5

То же, что и другие ответы, но как метод расширения:

static class Extensions
{
    public static void SetCommandTimeout(this IObjectContextAdapter db, TimeSpan? timeout)
    {
        db.ObjectContext.CommandTimeout = timeout.HasValue ? (int?) timeout.Value.TotalSeconds : null;
    }
}

Ответ 6

В сгенерированном коде конструктора он должен вызвать OnContextCreated()

Я добавил этот частичный класс для решения проблемы:

partial class MyContext: ObjectContext
{
    partial void OnContextCreated()
    {
        this.CommandTimeout = 300;
    }
}

Ответ 7

Для первой базы данных Aproach:

Мы все еще можем установить его в конструкторе, переопределив шаблон ContextName.Context.tt T4 следующим образом:

<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext
{
    public <#=code.Escape(container)#>()
        : base("name=<#=container.Name#>")
    {
        Database.CommandTimeout = 180;
<#
if (!loader.IsLazyLoadingEnabled(container))
{
#>
        this.Configuration.LazyLoadingEnabled = false;
<#
}

Database.CommandTimeout = 180; - это изменение acutaly.

Сгенерированный вывод:

public ContextName() : base("name=ContextName")
{
    Database.CommandTimeout = 180;
}

Если вы измените модель базы данных, этот шаблон останется, но актуальный класс будет обновлен.