Tempos de espera do Framework de Entidade

Estou recebendo tempos limite usando o Entity Framework (EF) ao usar uma importação de function que leva mais de 30 segundos para ser concluída. Eu tentei o seguinte e não consegui resolver esse problema:

Eu adicionei Default Command Timeout=300000 à cadeia de conexão no arquivo App.Config no projeto que possui o arquivo EDMX como sugerido aqui .

Esta é a aparência da minha string de conexão:

  

Eu tentei definir o CommandTimeout no meu repository diretamente assim:

 private TrekEntities context = new TrekEntities(); public IEnumerable GetKirksFriends() { this.context.CommandTimeout = 180; return this.context.GetKirksFriends(); } 

O que mais eu posso fazer para que a EF chegue ao tempo limite? Isso só acontece para conjuntos de dados muito grandes. Tudo funciona bem com pequenos conjuntos de dados.

Aqui está um dos erros que estou recebendo:

System.Data.EntityCommandExecutionException: Ocorreu um erro ao executar a definição de comando. Consulte a exceção interna para obter detalhes. —> System.Data.SqlClient.SqlException: o tempo limite expirou. O período de tempo limite decorrido antes da conclusão da operação ou o servidor não está respondendo.


OK – eu tenho esse trabalho e é bobo o que aconteceu. Eu tinha tanto a seqüência de conexão com tempo Default Command Timeout=300000 e o CommandTimeout definido como 180. Quando eu removi o tempo Default Command Timeout da seqüência de conexão, funcionou. Então a resposta é definir manualmente o CommandTimeout no seu repository em seu object de contexto da seguinte forma:

 this.context.CommandTimeout = 180; 

Aparentemente, definir as configurações de tempo limite na seqüência de conexão não tem efeito sobre ele.

Há um bug conhecido ao especificar o tempo limite de comando padrão na string de conexão EF.

http://bugs.mysql.com/bug.php?id=56806

Remova o valor da cadeia de conexão e configure-o no próprio object de contexto de dados. Isso funcionará se você remover o valor conflitante da string de conexão.

Entidade Framework Core 1.0:

 this.context.Database.SetCommandTimeout(180); 

Entidade Framework 6:

 this.context.Database.CommandTimeout = 180; 

Entidade Framework 5:

 ((IObjectContextAdapter)this.context).ObjectContext.CommandTimeout = 180; 

Entidade Framework 4 e abaixo:

 this.context.CommandTimeout = 180; 

Se você estiver usando um DbContext, use o construtor a seguir para definir o tempo limite do comando:

 public class MyContext : DbContext { public MyContext () { var adapter = (IObjectContextAdapter)this; var objectContext = adapter.ObjectContext; objectContext.CommandTimeout = 1 * 60; // value in seconds } } 

Se você estiver usando o DbContext e o EF v6 +, como alternativa, você pode usar:

 this.context.Database.CommandTimeout = 180; 

Normalmente eu ligo minhas operações dentro de uma transação . Como experimentei, não é suficiente definir o tempo limite do comando de contexto, mas a transação precisa de um construtor com um parâmetro de tempo limite. Eu tive que definir os valores de tempo limite para que ele funcionasse corretamente.

 int? prevto = uow.Context.Database.CommandTimeout; uow.Context.Database.CommandTimeout = 900; using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, TimeSpan.FromSeconds(900))) { ... } 

No final da function, defino o tempo limite do comando para o valor anterior em prevto.

Usando o EF6

Eu sei que isso é um thread muito antigo, mas a EF ainda não corrigiu isso. Para pessoas que usam o DbContext gerado automaticamente, você pode usar o seguinte código para definir o tempo limite manualmente.

 public partial class SampleContext : DbContext { public SampleContext() : base("name=SampleContext") { this.SetCommandTimeOut(180); } public void SetCommandTimeOut(int Timeout) { var objectContext = (this as IObjectContextAdapter).ObjectContext; objectContext.CommandTimeout = Timeout; } 

Isso é o que eu financiei. Talvez isso ajude alguém:

Aqui vamos nos:

Se você usa o LINQ com o EF procurando por alguns elementos exatos contidos na lista como este:

 await context.MyObject1.Include("MyObject2").Where(t => IdList.Contains(t.MyObjectId)).ToListAsync(); 

tudo está indo bem até IdList contém mais de um Id.

O problema de “timeout” será exibido se a lista contiver apenas um Id. Para resolver o problema, use if condition para verificar o número de ids em IdList.

Exemplo:

 if (IdList.Count == 1) { result = await entities. MyObject1.Include("MyObject2").Where(t => IdList.FirstOrDefault()==t. MyObjectId).ToListAsync(); } else { result = await entities. MyObject1.Include("MyObject2").Where(t => IdList.Contains(t. MyObjectId)).ToListAsync(); } 

Explicação:

Simplesmente tente usar o Sql Profiler e marque a opção Select statement generated by Entity frameeork. …

Se você estiver usando o Entity Framework como eu, defina o Tempo limite na class Startup da seguinte maneira:

  services.AddDbContext(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), o => o.CommandTimeout(180)));