web-dev-qa-db-fra.com

Entity Framework - quelle est la valeur du délai d'attente de commande actuel

J'utilise Entity Framework 5 et je souhaite connaître le délai d'expiration de la commande.

Pour ce faire, je convertis l'objet dbContext en ObjectContext et j'accède à la propriété CommandTimeout.

int ? currentCommandTimeout = ((IObjectContextAdapter)dbContext).ObjectContext.CommandTimeout;

La valeur actuelle de cette propriété est null, ce qui signifie que le délai d'attente de la commande actuelle est la valeur par défaut du fournisseur sous-jacent.

  1. Qui est le fournisseur sous-jacent? 
  2. Comment puis-je lire (via le code EF) la valeur de délai d'attente de commande actuelle dans ce cas?

Référence de la propriété MSDN ObjectContext CommandTimeout

EDIT: Merci d’avoir expliqué comment définir le délai d’exécution de la commande et avoir trouvé la valeur de délai d’exécution par défaut dans la documentation. Cependant, la question reste ouverte. Comment, si possible, pouvez-vous lire la valeur du délai d'attente de la commande en cas de défaut, via EF.

17
Oren

De MSDN,

  • La propriété CommandTimeout obtient ou définit la valeur de délai d'attente, en secondes, pour toutes les opérations de contexte d'objet.
  • Une valeur null indique que la valeur par défaut du fournisseur sous-jacent sera utilisée.

Ainsi, si vous ne le définissez pas explicitement par le code ou ne le passez pas dans votre chaîne de connexion (en MySQL), il s'agit de la valeur par défaut de votre fournisseur.

Si vous souhaitez afficher une valeur non nulle pour CommandTimeout, vous devez la transmettre dans connectionString ou la définir via le code.

Qui est le fournisseur sous-jacent?

Le fournisseur sous-jacent est celui que vous transmettez dans votre chaîne de connexion sous la forme providerName

<connectionStrings>
  <clear />
  <add name="Name" 
   providerName="System.Data.ProviderName" 
   connectionString="Valid Connection String;" />
</connectionStrings>

Ici, System.Data.ProviderName est votre fournisseur sous-jacent.

Si vous utilisez MySql ou MS Sql, selon le Documentation MySql et MSDN ,

  • La valeur par défaut est 30 secs
  • Une valeur de 0 indique une attente indéfinie et doit être évitée.

    Remarque : 

Le délai d'expiration de la commande par défaut peut être modifié à l'aide de l'attribut connectionstring Default Command Timeout dans le cas des fournisseurs de base de données MySQL.

18
Bhushan Firake

Si vous utilisez SQLServer, le délai d'expiration de la commande par défaut est de 30 secondes.

Propriété SqlCommand.CommandTimeout

4
Jason Massey

Cela devrait marcher

var ctx = new DbContext();
ctx.Database.CommandTimeout = 120;
4
afr0
  1. Qui est le fournisseur sous-jacent?

Pour vous connecter à une base de données à distance et lancer des requêtes SQL, vous avez besoin d'un mécanisme ou d'un médiateur (vous pouvez dire) qui comprend la sémantique de communication des différentes actions à effectuer lors du lancement d'une requête, par exemple. créer une commande, établir une connexion, gérer le délai de connexion, réessayer, etc.

Toutes ces responsabilités sont assumées par les fournisseurs pour la base de données à laquelle vous essayez de vous connecter. Ces fournisseurs auront différentes implémentations et classes w.r.t. l'environnement à partir duquel vous vous connectez (C #, Java, Python, Perl, etc.). Donc, pour vous connecter à une base de données MySQL, vous aurez différents fournisseurs pour le monde de la programmation Java, .net ou python.

  1. Comment puis-je lire (via le code EF) la valeur de délai d'attente de commande actuelle dans ce cas?

Nan. Ce n'est pas possible. Si vous examinez de près la propriété dbContext.Database.CommandTimeout, elle est de type int?. Donc, la logistique de garder cette propriété en tant que nullable int consiste uniquement à représenter la valeur par défaut (en tant que null). Entity Framework (EF) n’expose rien tant que vous n’avez pas défini de valeur explicite dans le code C #. J'ai vérifié cela par rapport aux bases de données suivantes

  • MySQL
  • Serveur SQL

Dans les deux cas, je constate qu'après la création de l'objet de contexte de base de données, la propriété d'expiration de commande est définie sur null, ce qui suggère qu'il utilise la valeur par défaut fournie par le fournisseur sous-jacent.

Mais oui, si vous avez défini une valeur non nulle une fois dans votre code C # à travers la propriété dbContext.Database.CommandTimeout, vous pouvez bien sûr la relire car il s'agit d'une propriété get-set sur l'objet de commande. Il vous montrera toujours la nouvelle valeur qui a été définie explicitement dans le code. 

Si vous le redéfinissez sur null, EF recommencera à utiliser le délai d’expiration par défaut du fournisseur sous-jacent.

Utilisation de classes de fournisseur au lieu de la couche EF: si vous n’utilisez pas la couche ORM du framework d’entité ni les classes principales du fournisseur, vous pouvez certainement voir la valeur du délai d’expiration par défaut lors de l’initialisation proprement dite. Comme lorsque j'ai exécuté ci-dessous le code mentionné pour une base de données MySQL avec une valeur de délai d'expiration de commande par défaut déjà définie dans la chaîne de connexion elle-même, vous obtenez alors 40.

private static void TestingCommandTimeOutInMySql()
        {
            string connetionString = "Server=localhost;Database=sakila;Uid=root;Pwd=Passw0rd;default command timeout=40;";
            MySqlConnection con = new MySqlConnection(connetionString);
            try
            {
                cnn.Open();
                Console.WriteLine("Connection Open ! ");
                MySqlCommand cmd = new MySqlCommand("select * from actor", con);
                var timeoutValue = cmd.CommandTimeout; //shows 40
                con.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Can not open connection ! ");
            }
        }

Si vous ne définissez rien dans la chaîne de connexion, la valeur par défaut de 30 est indiquée pour MySQL. Ici, la CommandTimeout est int, NOT int?. Donc, EF applique certainement une certaine intelligence tout en exposant cette propriété des classes de fournisseurs qui sont finalement exposées par EF via dbContext.Database.CommandTimeout. EF ne fait que masquer ces classes de fournisseurs avec une intelligence supplémentaire.

Quelques détails supplémentaires concernant les piqûres de connexion:

(Pour le fournisseur SQL Server:} _ Les formats de chaîne de connexion au serveur Microsoft SQL ne fournissent aucune propriété à l'aide de laquelle vous pouvez définir un délai d'expiration d'exécution de commande personnalisé. Il est donc tout simplement impossible de définir une valeur lors de l'initialisation du fournisseur SQL Server. Vous pouvez toujours modifier la valeur dans le code C # mais après l’initialisation/initialisation. Vous pouvez voir plus de détails ici .

Pour le fournisseur MySQL:} _ Les formats de chaîne de connexion SQL prennent en charge la définition explicite du délai d'expiration de la commande par défaut. Vous pouvez trouver les détails ici . Vous pouvez mentionner une valeur de délai d'expiration de commande par défaut personnalisée dans la chaîne de connexion MySQL comme ceci: 

default command timeout=200;
3
RBT

C'est comme ça que je le fais.

ObjectContext objectContext = ((IObjectContextAdapter)dbContext).ObjectContext
int commandTimeout = objectContext.CommandTimeout 
    ?? objectContext.Connection.CreateCommand().CommandTimeout;
1
enoshixi