395 votes

Délais d'attente d'Entity Framework

J'obtiens des délais d'attente en utilisant Entity Framework (EF) lors de l'utilisation d'une importation de fonction qui prend plus de 30 secondes pour se terminer. J'ai essayé ce qui suit et je n'ai pas réussi à résoudre ce problème :

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

Voici à quoi ressemble ma chaîne de connexion :

<add 
    name="MyEntityConnectionString" 
    connectionString="metadata=res://*/MyEntities.csdl|res://*/MyEntities.ssdl|
       res://*/MyEntities.msl;
       provider=System.Data.SqlClient;provider connection string=&quot;
       Data Source=trekdevbox;Initial Catalog=StarTrekDatabase;
       Persist Security Info=True;User ID=JamesTKirk;Password=IsFriendsWithSpock;
       MultipleActiveResultSets=True;Default Command Timeout=300000;&quot;"
    providerName="System.Data.EntityClient" />

J'ai essayé de définir le CommandTimeout dans mon référentiel directement comme ceci :

private TrekEntities context = new TrekEntities();

public IEnumerable<TrekMatches> GetKirksFriends()
{
    this.context.CommandTimeout = 180;
    return this.context.GetKirksFriends();
}

Que puis-je faire d'autre pour empêcher l'EF de tomber en panne ? Cela ne se produit que pour les très grands ensembles de données. Tout fonctionne bien avec les 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 : Timeout expired. Le délai d'attente s'est écoulé avant l'achèvement de l'opération ou le serveur ne répond pas.


OK - J'ai réussi à le faire fonctionner et c'est idiot ce qui s'est passé. J'avais à la fois la chaîne de connexion avec Default Command Timeout=300000 et le CommandTimeout fixé à 180. Lorsque j'ai retiré le Default Command Timeout de la chaîne de connexion, ça a marché. La réponse est donc de définir manuellement le CommandTimeout dans votre référentiel sur votre objet de contexte comme suit :

this.context.CommandTimeout = 180;

Apparemment, le paramétrage du délai d'attente dans la chaîne de connexion n'a aucun effet.

0 votes

Supprimer " de la chaîne de connexion

0 votes

5 votes

@hamlin11 Dans une chaîne de connexion EF, cela est nécessaire pour définir quelle partie est une chaîne de connexion et quelle partie est une métadonnée EF. Laissez &quot; dans la chaîne.

661voto

Alex Ford Points 15277

Il y a 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'objet de contexte de données lui-même. Cela fonctionnera si vous supprimez la valeur conflictuelle 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 inférieur :

this.context.CommandTimeout = 180;

5 votes

Comment puis-je réaliser cela en utilisant edmx ?

0 votes

@iroel Le fichier modèle EDMX n'expose pas ces propriétés sur le contexte de données. Vous devez accéder à la propriété du contexte de données en utilisant l'une des méthodes ci-dessus.

2 votes

Dans quelle version de l'EntityFramework ce problème est-il résolu ? Je ne trouve pas le bug EF correspondant.

106voto

saille Points 3585

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

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

3 votes

@ErickPetru, donc vous pouvez facilement le changer pour un nombre différent de minutes :), aussi je ne serais pas trop surpris si le compilateur optimise cette multiplication !

2 votes

@JoelVerhagen, ne soyez pas surpris. Voici une bonne explication du moment où l'optimisation automatique se produit : stackoverflow.com/questions/160848/ . Dans ce cas, je suppose que cela peut arriver (puisqu'il s'agit de deux valeurs littérales), mais honnêtement, je pense que le code est un peu étrange de cette façon.

51 votes

Meh...les enfants meurent de faim...qui se soucie de 1*60 ?

55voto

Paul Points 141

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

this.context.Database.CommandTimeout = 180;

22voto

parismiguel Points 195

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

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

15voto

pillesoft Points 460

En général, je gère mes opérations dans le cadre d'un transaction . D'après mon expérience, il ne suffit pas de définir le délai d'attente de la commande contextuelle, mais la transaction doit avoir un constructeur avec un paramètre de délai d'attente. J'ai dû définir les deux valeurs de délai d'attente 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))) {
...
}

À la fin de la fonction, je remets le délai de commande à la valeur précédente dans prevto.

Utilisation de l'EF6

0 votes

Ce n'est pas du tout une bonne approche. J'avais l'habitude d'ajouter beaucoup de transactions et cela devenait un cauchemar pour moi dans un projet. J'ai fini par remplacer toutes les transactions par un seul SAVEChanges() dans EF 6+. Vérifiez ceci coderwall.com/p/jnniww/

0 votes

Cette réponse devrait avoir un vote plus élevé. J'ai essayé toutes les différentes façons d'augmenter le délai d'attente mais ce n'est que lorsque j'ai défini à la fois le délai d'attente de la commande contextuelle et la portée de la transaction que cela a fonctionné.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X