IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Accès aux données Discussion :

[C#] Comment gérer correctement mes requetes ?


Sujet :

Accès aux données

  1. #1
    Membre chevronné Avatar de Jinroh77
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2006
    Messages
    1 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Février 2006
    Messages : 1 964
    Points : 2 145
    Points
    2 145
    Par défaut [C#] Comment gérer correctement mes requetes et ma connection ?
    Bonjour à tous.
    Je suis en train de travailler sur mon prmeier projet .NET et je tiens à faire une classe de connection et de requete propre et réutilisable evidement
    Je travaille sans DataSet mais avec des DataReader.
    Pour effectuer mes requete sur ma base SQL Server, j'utilise une classe clRequete qui elle même utilise une classe clConnection.
    Ma classe clRequete contient un string (ma requete) et un objet de type clConnection.
    Une petite idée de la classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
     private string sRequete;
     public SqlDataReader QueryRequete()
    {
       clConnection connection = new clConnection();
       //strRequete = ValidationStrRequete(strRequete);
       SqlCommand command = new SqlCommand(this.sRequete,
     connection.getCurseur());
       try
       {
          return command.ExecuteReader();
       }
       catch (SqlException ex)
       {
         ViewException(ex);
         return null;
       }
     }
     public Object NonQueryRequete()
     {
       clConnection connection = new clConnection();
       SqlCommand command = new SqlCommand(this.sRequete,
     connection.getCurseur());
       try
       {
         return command.ExecuteScalar();
       }
       catch (SqlException ex)
       {
         ViewException(ex);
         return null;
       }
     }
    Au départ j'utilisais une classe clConnection assez simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    private SqlConnection curseur;
     
    public clConnection()
    {
      try
      {
      curseur = new SqlConnection(Properties.Settings.Default.connectString);
      curseur.Open();
     }
     catch (Exception ex)
     {
       MessageBox.Show("Echec de connection à la Base de Données", "Erreur
     de connection", MessageBoxButtons.OK, MessageBoxIcon.Error);
       System.Diagnostics.Debug.WriteLine(ex.ToString());
      }
    }
    public SqlConnection getCurseur()
    {
       return this.curseur;
    }
    Malheureusement je me suis rendu compte qu'il ouvrait plusieurs dizaine de connection à la base, en fait à chqaue fois que je faisais une requete....
    Je me suis alros renseigné sur le sujet et j'ai trouvé des aides comme celle-ci
    Malheureusement je n'arrive pas à m'en servir, soit le lecteur est fermé, soit je n'ai pas fermé un dataReader, soit la connection est déjà ouverte etc....
    Elle ne sont pas cool avec moi ces classes...

    Merci pour votre aide

  2. #2
    Membre chevronné
    Avatar de Piotrek
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2004
    Messages
    869
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Mars 2004
    Messages : 869
    Points : 1 904
    Points
    1 904
    Par défaut
    Salut

    En fait pour le datareader t'as pas trop le choix... un datareader doit avoir sa connection exclusive
    Apres si t'as des ennuis de connection, voila qqes conseils:
    - Les connections (et donc les datareader) il faut les ouvrir les plus tard possible, [faire tes operations / chargements d'objets], et les refermer les plus tot possible
    - Ca sert a rien de tenter de reutiliser des connections, autant en ouvrir de nouvelles (apres avoir bien entendu referme celles en cours d'utilisation) Il existe un mechanisme qui se charge de mettre en cache les connections actives (cela se nomme le pooling, fais une recherche sur le forum pour plus d'infos)

  3. #3
    Membre chevronné Avatar de Jinroh77
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2006
    Messages
    1 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Février 2006
    Messages : 1 964
    Points : 2 145
    Points
    2 145
    Par défaut
    Désolé pour le retard.

    Merci pour cette première idée.
    Donc ce qui est instance de connection, que l'on eput voir à plusieurs endroit, je laisse tomber, je garde mes classes de Requete et Connection comme elles sont, et je revérifie mon code pour être sûr de ne pas laisser de DataReader ouvert ?

    Merci

  4. #4
    Membre chevronné Avatar de Jinroh77
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2006
    Messages
    1 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Février 2006
    Messages : 1 964
    Points : 2 145
    Points
    2 145
    Par défaut
    Pourquoi est-ce que mes connections restent ouvertes une fois la Requete effectuée ?

    Je m'explique.
    Je crée mon Objet cRequete, il utilise son curseur de connection pour effectuer mes requetes SQL.

    Je fais une fermeture de connection :
    Où j'ai créée mon objet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cRequete.CloseConnection();
    et dans ma classe cRequete
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    public void CloseConnection()
    {
       try
       {
          this.cConnection.cpCurseur.Close();
       }
       catch (NullReferenceException)
       {
       }
    }
    Donc pour le coup j'ai bien l'état de mon curseur à 'Closed' mais ce qui me gène est que lorsque je regarde le moniteur d'activité de SQL Server 2005, il m'affiche toujours mes processus avec en détails la commande SQL de la dernière effectuée avec mon objet Requete.
    Je pensais que une fois la connection à State : Closed, la connection ne s'afficherais plus.

    Merci pour vos explications.

  5. #5
    Expert éminent
    Avatar de neguib
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 627
    Détails du profil
    Informations personnelles :
    Âge : 64
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 627
    Points : 7 879
    Points
    7 879
    Par défaut
    Piotrek t'a déjà en partie répondu
    Citation Envoyé par Piotrek
    Ca sert a rien de tenter de reutiliser des connections, autant en ouvrir de nouvelles (apres avoir bien entendu referme celles en cours d'utilisation) Il existe un mecanisme qui se charge de mettre en cache les connections actives (cela se nomme le pooling, fais une recherche sur le forum pour plus d'infos)
    Ceci est une gestion propre de SqlServer qui s'en arrange ainsi histoire de rendre plus rapide une nouvelle connection équivalente

  6. #6
    Membre chevronné Avatar de Jinroh77
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2006
    Messages
    1 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Février 2006
    Messages : 1 964
    Points : 2 145
    Points
    2 145
    Par défaut
    Ah vi c'est donc lui...
    Mais alors, n'y a-t-il pas un moyen de voir les connection vraiment active ?
    Histoire de voir à quel point je sature les connections à ma base ?
    Savoir si les pool présent ne sont pas trop nombreux etc... ?

    Merci pour tout

  7. #7
    Membre chevronné
    Avatar de Piotrek
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2004
    Messages
    869
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Mars 2004
    Messages : 869
    Points : 1 904
    Points
    1 904
    Par défaut
    J'ai jamais eu a modifier les valeurs par defaut du pooling (tu le pilote par la connectionstring)

    Pour auditer ce qui se passe c'est simple:
    - Soit avec les compteurs de performances de la machine locale
    - Soit avec les compteurs de performances du serveur (valeurs sql server)
    - Soit dans sql server, tu regarde les connections actives

    Tout depend a quel niveau tu veux auditer les connections

  8. #8
    Membre chevronné Avatar de Jinroh77
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2006
    Messages
    1 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Février 2006
    Messages : 1 964
    Points : 2 145
    Points
    2 145
    Par défaut
    J'ai mis la velur Pooling à false dans ma connectString et après quelques modifications de mon code, j'avais bien mes connections qui disparaissaient dans l'activity monitor.
    Par contre je me demande si mon code est vraiment bon au niveau de la gestion de mes requètes.
    Je procède de la manière suivantes :

    Dans mes méthodes qui ont besoin de liaison à la BDD
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    clRequete cRequeteFed = new clRequete("SELECT ID_FEDERATION,
     ID_BAR, TAUX, LIBELLE FROM XC_FED WHERE NUMERO = " + dNumFed);
    SqlDataReader drFed = cRequeteFed.QueryRequete();
    drFed.Read();
    .......
    drFed.Close();
    cRequeteFed.CloseConnection();
    Et ma classe clRequete
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
     
    private string sRequete;
    clConnection cConnection = new clConnection();
     
    public string spRequete
    {
        get { return sRequete; }
        set { sRequete = value; }
    }
     
    public clRequete() { }
    public clRequete(string sRequete)
    {
        this.sRequete = sRequete;
    }
     
    public SqlDataReader QueryRequete()
    {
        //strRequete = ValidationStrRequete(strRequete);
        OpenConnection();
        SqlCommand command = new SqlCommand(this.sRequete,
     cConnection.cpCurseur);
        try
        {
            return command.ExecuteReader();
        }
        catch (SqlException ex)
        {
            ViewException(ex);
            return null;
        }
    }
    public Object NonQueryRequete()
    {
        OpenConnection();
        SqlCommand command = new SqlCommand(this.sRequete,
     cConnection.cpCurseur);
        try
        {
            return command.ExecuteScalar();
        }
        catch (SqlException ex)
        {
            ViewException(ex);
            return null;
        }
    }
     
    public void CloseConnection()
    {
        try
        {
            this.cConnection.cpCurseur.Close();
        }
        catch (NullReferenceException)
        {
            MessageBox.Show("Connection déjà fermée");
        }
    }
    public void OpenConnection()
    {
       if (this.cConnection.cpCurseur.State != ConnectionState.Open)
        {
            try
            {
                this.cConnection.cpCurseur.Open();
            }
            catch (Exception)
            {
                MessageBox.Show("Connection déjà ouverte");
            }
        }
    }
    Merci pour vos avis.

  9. #9
    Membre chevronné
    Avatar de Piotrek
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2004
    Messages
    869
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Mars 2004
    Messages : 869
    Points : 1 904
    Points
    1 904
    Par défaut
    Il n'y a pas de methode universelle, tout depend du contexte

    Que fait "cConnection.cpCurseur.Close()" ?

    Il faut bien verifier que cela referme la connection

  10. #10
    Membre chevronné Avatar de Jinroh77
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2006
    Messages
    1 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Février 2006
    Messages : 1 964
    Points : 2 145
    Points
    2 145
    Par défaut
    cpCursuer est le SqlConnection de ma classe ClConnection.
    C'est bien sur lui que dois se faire le Close() ?
    En désactivant le pooling, d'après ce que j'ai vu ça semblait efficace, miantenant je voulais être sûr que ma méthode était relativement propre.

    Ce qui me gène, que je trouve contraignant est de devoir utiliser cette méthode cRequete.CloseConnection().
    De devoir fermer le reader : OK on a pas trop le choix. Maintenant pour la connection....
    Dans l'idéal, ma classe Requete, renvoyait (sous forme d'objet les résultats d'une NonQuery Requete et sous forme de SqlDataReader les résultats d'une Query Requete) et se refermait de suite.

    Merci à toi.

  11. #11
    Expert éminent
    Avatar de neguib
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 627
    Détails du profil
    Informations personnelles :
    Âge : 64
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 627
    Points : 7 879
    Points
    7 879
    Par défaut
    Ton souci est-il Jinroh77

  12. #12
    Membre chevronné
    Avatar de Piotrek
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2004
    Messages
    869
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Mars 2004
    Messages : 869
    Points : 1 904
    Points
    1 904
    Par défaut
    Je crois avoir saisi le principe, cependant un SqlDataReader a besoin d'une connection ouverte le temps qu'il est utilise, le probleme vient peut etre de la

  13. #13
    Membre chevronné Avatar de Jinroh77
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2006
    Messages
    1 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Février 2006
    Messages : 1 964
    Points : 2 145
    Points
    2 145
    Par défaut
    Citation Envoyé par neguib
    Ton souci est-il Jinroh77
    C'est quasiment terminé, je posais juste des petites questions sur les d'optimisation possible.
    Mais c'est bon je vais le marquer.

    Citation Envoyé par Piotrek
    Je crois avoir saisi le principe, cependant un SqlDataReader a besoin d'une connection ouverte le temps qu'il est utilise, le probleme vient peut etre de la
    C'est ce dont je me suis rendu compte pendant mes tests
    Je vais continuer à utiliser mes requêtes de la sorte en attendant mieux, il faut que je m'active sur le projet.

    Merci vous et à très bientôt


    P.S. : si quelqu'un à une belle méthode toute propre qui correspond à peu près à ce dont j'ai besoin, je suis preneur pour y jeter un oeil

  14. #14
    Membre chevronné
    Avatar de Piotrek
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2004
    Messages
    869
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Mars 2004
    Messages : 869
    Points : 1 904
    Points
    1 904
    Par défaut
    Il n'y a pas de solution ideale

    tout depend de tes besoins, cependant tu peux t'inspirer de ceci par ex:
    http://nx.developpez.com/articles/dac/
    pour faire un acces aux donnees a de multiples bases (si ca fait partie de tes besoins)

  15. #15
    Membre chevronné Avatar de Jinroh77
    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2006
    Messages
    1 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Février 2006
    Messages : 1 964
    Points : 2 145
    Points
    2 145
    Par défaut
    Merci pour ce lien très interessant, il me permettra de nettoyer un peu ma solution.
    Par contre la partie "5.4 La cas du DataReader" confirme ce que l'on disait, c'est dans le code client que je dois m'occuper de fermer la connection puisqu'elle doit resterr ouvet pendant la récupération des valeurs. Ce qui semble finalement logique vu les spécificités du DataReader.

    Merci

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment gérer correctement une exception ?
    Par [ZiP] dans le forum Général Python
    Réponses: 2
    Dernier message: 20/08/2013, 21h34
  2. Comment gérer correctement le réseau dans un FPS ?
    Par Acropole dans le forum Réseau et multijoueurs
    Réponses: 4
    Dernier message: 15/09/2011, 17h30
  3. comment trier correctement mes requêtes ?
    Par isodoro dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 21/03/2009, 16h12
  4. [TabItem] Comment gérer correctement les RoutedMessages sur un overrided ?
    Par ikeas dans le forum Windows Presentation Foundation
    Réponses: 7
    Dernier message: 02/10/2008, 13h28
  5. [.NET 2.0] Comment gérer correctement des sockets ?
    Par MattC dans le forum Framework .NET
    Réponses: 2
    Dernier message: 08/02/2006, 16h31

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo