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.

10voto

Shiva N Points 41

Je sais que c'est un très vieux fil de discussion, mais EF n'a toujours pas réglé ce problème. Pour les personnes utilisant des DbContext Vous pouvez utiliser le code suivant pour définir manuellement le délai d'attente.

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

1 votes

Ajoutez votre } manquant à la fin pour le partiel.

10voto

Nathaniel Points 105

Sur .Net Core (NetCore) utilisez la syntaxe suivante pour modifier le délai d'attente de 30 secondes par défaut à 90 secondes :

public class DataContext : DbContext
{
    public DataContext(DbContextOptions<DataContext> options) : base(options)
    {
        this.Database.SetCommandTimeout(90); // <-- 90 seconds
    }
}

3voto

tosjam Points 1

C'est ce que j'ai trouvé. Peut-être que cela aidera quelqu'un :

Donc, nous y voilà :

Si vous utilisez LINQ avec EF en recherchant certains é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 Id.

Le problème du "timeout" apparaît si la liste ne contient qu'un seul Id. Pour résoudre ce problème, utilisez une condition if pour vérifier le nombre d'identifiants 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 Entity frameeork.

2voto

nzrytmn Points 531

Pour Entity Framework 6, j'utilise cette annotation et cela fonctionne bien.

  public partial class MyDbContext : DbContext
  {
      private const int TimeoutDuration = 300;

      public MyDbContext ()
          : base("name=Model1")
      {
          this.Database.CommandTimeout = TimeoutDuration;
      }
       // Some other codes
    }

Le paramètre CommandTimeout est un entier nullable qui définit les valeurs de délai d'attente en secondes. en secondes, si vous définissez null ou si vous ne définissez rien, les valeurs par défaut seront utilisées. du fournisseur que vous utilisez.

0voto

David Greenfeld Points 11

En ajoutant ce qui suit à ma procédure stockée, j'ai résolu l'erreur de dépassement de délai :

SET NOCOUNT ON;
SET ARITHABORT ON;

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