Délais d’expiration de l’entité

J’obtiens des délais d’attente avec Entity Framework (EF) lorsque vous utilisez une importation de fonctions qui prend plus de 30 secondes. J’ai essayé les solutions suivantes et je n’ai pas pu résoudre ce problème:

J’ai ajouté le Default Command Timeout=300000 à la chaîne de connexion dans le fichier App.Config du projet contenant le fichier EDMX, comme suggéré ici .

Voici à quoi ressemble ma chaîne de connexion:

  

J’ai essayé de configurer le CommandTimeout dans mon référentiel directement comme ceci:

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

Que puis-je faire d’autre pour que le FE prenne fin? Cela ne se produit que pour les très grands ensembles de données. Tout fonctionne bien avec de petits ensembles de données.

Voici l’une des erreurs que je reçois:

System.Data.EntityCommandExecutionException: une erreur s’est produite lors de l’exécution de la définition de la commande. Voir l’exception interne pour plus de détails. —> System.Data.SqlClient.SqlException: expiration du délai d’attente. Le délai d’attente s’est écoulé avant la fin de l’opération ou le serveur ne répond pas.


OK – J’ai ce travail et c’est idiot ce qui s’est passé. J’avais à la fois la chaîne de connexion avec le Default Command Timeout=300000 et le paramètre CommandTimeout défini sur 180. Lorsque j’ai supprimé le Default Command Timeout de Default Command Timeout de la chaîne de connexion, cela fonctionnait. Donc, la réponse est de définir manuellement le CommandTimeout dans votre référentiel sur votre object de contexte comme suit:

 this.context.CommandTimeout = 180; 

Apparemment, définir les parameters de délai d’attente dans la chaîne de connexion n’a aucun effet sur elle.

Il existe un bogue connu avec la spécification du délai de commande par défaut dans la chaîne de connexion EF.

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

Supprimez la valeur de la chaîne de connexion et définissez-la sur l’object de contexte de données lui-même. Cela fonctionnera si vous supprimez la valeur en conflit de la chaîne de connexion.

Entity Framework Core 1.0:

 this.context.Database.SetCommandTimeout(180); 

Entity Framework 6:

 this.context.Database.CommandTimeout = 180; 

Entity Framework 5:

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

Entity Framework 4 et ci-dessous:

 this.context.CommandTimeout = 180; 

Si vous utilisez un DbContext, utilisez le constructeur suivant pour définir le délai d’expiration de la commande:

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

Si vous utilisez DbContext et EF v6 +, vous pouvez également utiliser:

 this.context.Database.CommandTimeout = 180; 

Habituellement, je gère mes opérations dans une transaction . Comme je l’ai vu, il ne suffit pas de définir le délai d’expiration de la commande de contexte, mais la transaction nécessite un constructeur avec un paramètre de délai d’attente. J’ai dû définir les deux valeurs de time out pour que cela fonctionne correctement.

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

A la fin de la fonction, je ramène le délai de commande à la valeur précédente dans prevto.

En utilisant EF6

Je sais que c’est un très vieux thread en cours d’exécution, mais toujours EF n’a pas résolu ce problème. Pour les utilisateurs de DbContext générés DbContext pouvez utiliser le code suivant pour définir le délai d’attente manuellement.

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

C’est ce que je finance. Peut-être que cela aidera quelqu’un:

Alors on y va:

Si vous utilisez LINQ avec EF pour rechercher des éléments exacts contenus dans la liste comme ceci:

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

tout se passe bien jusqu’à ce que IdList contienne plus d’un identifiant.

Le problème de «timeout» apparaît si la liste ne contient qu’un seul identifiant. Pour résoudre le problème, utilisez if condition pour vérifier le nombre d’ID dans IdList.

Exemple:

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

Explication:

Essayez simplement d’utiliser Sql Profiler et vérifiez l’instruction Select générée par l’entité frameeork. …

Si vous utilisez Entity Framework comme moi, vous devez définir Time out sur la classe Startup comme suit:

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