Definir tempo limite do banco de dados no Entity Framework

164

Meu comando continua atingindo o tempo limite; portanto, preciso alterar o valor padrão do tempo limite do comando.

Eu encontrei myDb.Database.Connection.ConnectionTimeout, mas é readonly.

Como posso definir o tempo limite do comando no Entity Framework 5 ?

James
fonte
20
FYI, no EF6, Database.CommandTimeoutnão é mais somente leitura
itsho 25/06
2
@itsho Ele estava falando Database.Connection.ConnectionTimeout. Enfim, eu diria que Database.CommandTimeouté a coisa certa no caso de sua consulta exceder o tempo limite ( System.Data.Entity.Core.EntityCommandExecutionExceptioncontendo exceção System.Data.SqlClient.SqlException: Timeout expired.).
David Ferenczy Rogožan 4/03/16
2
Possível duplicata de tempos limite da estrutura
Tim Pohlmann
1
Eu suponho que você realmente não se importa com o tempo limite de CONNECTION, mas, em vez disso, deseja ajustar o tempo limite de COMMAND.
precisa saber é o seguinte

Respostas:

199

Tente isso no seu contexto:

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

Se você deseja definir o tempo limite na cadeia de conexão, use o Connection Timeoutparâmetro como na seguinte cadeia de conexão:

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

Fonte: Como: Definir a Cadeia de Conexão

Leniel Maccaferri
fonte
1
Eu recomendaria usar a versão da cadeia de conexão como se você tentasse acessar o ObjectContextneste construtor às vezes os comandos do console do PowerShell / NuGet falharão de maneira circular .
Kevin Gorski
130
Tempo limite de conexão e CommandTimeout e duas coisas separadas. A configuração da cadeia de conexão, Tempo Limite da Conexão, não afetará a quantidade de tempo que o comando é executado (CommandTimeout).
22413 Clay Lenhart
3
Meu problema era um pouco diferente. Eu tenho tempo limite durante as migrações. EF tem uma propriedade similar ao set para usar durante as migrações: msdn.microsoft.com/en-us/library/...
Karsten
2
Dependendo da versão do EF usada, consulte esta resposta para ter uma idéia das diferentes APIs em como especificar a propriedade CommandTimeout.
Jim Aho
1
Não funciona para mim (conexão vs comando não sendo a mesma coisa que suspeito). Este post resolvido-lo embora stackoverflow.com/questions/6232633/entity-framework-timeouts
Jezbers
181

Você pode usar DbContext.Database.CommandTimeout = 180;

É bem simples e não requer elenco.

Vu Nguyen
fonte
1
Muito útil para nós que usamos o Fluent APIformulário da EF.
GoldBishop
20

Meu contexto parcial se parece com:

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

Como saí do SetCommandTimeOutpúblico, apenas as rotinas necessárias para levar muito tempo (mais de 5 minutos) são modificadas em vez de um tempo limite global.

Erik Philips
fonte
9

No código do construtor gerado, ele deve chamar OnContextCreated()

Eu adicionei esta classe parcial para resolver o problema:

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

Estendi a resposta de Ronnie com uma implementação fluente para que você possa usá-la da seguinte maneira:

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));
    } 
}
Timmerz
fonte
8

Para o primeiro banco de dados, o Approach:

Ainda podemos defini-lo em um construtor, substituindo o modelo T4 ContextName.Context.tt desta maneira:

<#=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; é a mudança acutalmente.

A saída gerada é esta:

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

Se você alterar seu modelo de banco de dados, esse modelo permanecerá, mas a classe atualy será atualizada.

Christian Gollhardt
fonte
Existe uma maneira de especificar o tempo limite no modelo usando algum arquivo de configuração.?
shas 14/09/16
1
não tenho certeza, se houver algo em construção (eu não consegui encontrar algo). Mas em vez de codificar 180, você pode usar System.Configuration.ConfigurationManager.AppSettings["keyname"]@shas
Christian Gollhardt
7

O mesmo que as outras respostas, mas como um método de extensão:

static class Extensions
{
    public static void SetCommandTimeout(this IObjectContextAdapter db, TimeSpan? timeout)
    {
        db.ObjectContext.CommandTimeout = timeout.HasValue ? (int?) timeout.Value.TotalSeconds : null;
    }
}
Ronnie Overby
fonte
e como chamo esse método de extensão?
Wanderson López
1

Acabei de encontrar este problema e o resolvi atualizando o arquivo de configuração do aplicativo. Para a conexão em questão, especifique "Tempo Limite da Conexão = 60" (estou usando a versão 5.0.0.0 da estrutura da entidade)

Configuração ConnectionTimeout

Andrew Burrow
fonte
0

Você pode usar este simples:
dbContext.Database.SetCommandTimeout(300);

Hassan Muhammad Saad
fonte