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

C# Discussion :

Probleme avec SqlDataReader en sorti de methode erreur de conception?


Sujet :

C#

  1. #1
    Membre du Club
    Inscrit en
    Décembre 2003
    Messages
    102
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 102
    Points : 55
    Points
    55
    Par défaut Probleme avec SqlDataReader en sorti de methode erreur de conception?
    Bonjour tout le monde,

    J'ai un probleme avec du code que j'ai pas ecrit. Tout d'abord je suis pas un expert en ADO.NET. Mais ca va venir.

    Alors voila on est j'ai une methode qui renvoi un SqlDataReader.

    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
     
            public SqlDataReader getReader(string spName, object[,] cmdParams)
            {
                SqlCommand cmdData = null;
                SqlDataReader reader = null ;
     
                try
                {
                    cmdData = createCommand(spName, cmdParams);
                    if (cmdData == null) return null;
                    reader = cmdData.ExecuteReader();
                    return reader;
                }
                finally 
                {
                    reader.Close();
                }
    Comme vous vous en doutez cela ne fonctionne pas car le reader est ferme avant la sorti de la methode.
    Je ne peux donc pas utiliser le resultat de cette methode.

    Conclusion :

    Dois-je passer le SqlDataReader en parametre de la methode?
    Sachant que je suis dans une architecture 3 tiers, est-ce la meilleur solution?

    Bref je suis un peu perdu sur l'ADO ce que je cherche c'est la bonne pratique?

    Merci de votre aide.
    Superfly

  2. #2
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Points : 6 334
    Points
    6 334
    Par défaut
    Tu passes dans le finally avant de sortir de la méthode, donc tu fermes ton reader.
    Si tu veux attraper les exceptions, tu dois mettre un bloc catch. Le bloc finally est TOUJOURS exécuté, exception ou pas.

  3. #3
    Membre du Club
    Inscrit en
    Décembre 2003
    Messages
    102
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 102
    Points : 55
    Points
    55
    Par défaut
    Je te remercie SaumonAgile, je sais tout ca.

    Le but n'est pas de catcher les execptions mais de toujours fermer le reader.
    Catcher les exceptions n'a de sens que si tu sais quoi en faire.

    Mais c'est pas le debat, mon collegue qui a programmer la DAL
    met les exceptions sous le tapis, j'ai donc purement et simplement supprimer le catch...

    Imagine que j'enleve le "reader.close", a la prochaine execution de cette methode, une exception va etre levee disant en substance "un SqldataReader
    existe deja pour cette command" ce qui est normale, car il n'est pas clos.

    Je viens de parcourir de la litterature au sujet d'ADO.Net en fait il semble que le SqlDataReadar soit un element connecte ce qui ne convient pas a une utilisation deconnecte.

    En faite apres tout ce que je viens de lire, il semblerait que l'object qui convienne soit un DataSet qui lui est deconnecte et stocke en memoire et peut donc se promener entre les couches de mon application.

    En parcourant la DAL de mon collegue, je me suis rendu compte qu'il possede aussi une methode getData aui retourne un DataTable:

    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
     
            public DataTable getData(string spName, object[,] cmdParams)
            {
                //Declarations
                SqlCommand cmdData = null;
                SqlDataReader drResults = null;
                DataTable dtResults = null;
     
                try
                {
                    //Initialize Command
                    cmdData = createCommand(spName, cmdParams);
     
                    if (cmdData == null) return null;
     
                    //Execute Command
                    drResults = cmdData.ExecuteReader();
                    if (drResults.HasRows)
                    {
                        dtResults.Load(drResults);
                    }
                    else
                    {
                        dtResults = new DataTable("Empty");
                    }
     
                }
                catch (Exception ex)
                {
                    //Write Error
                    writeError("Could not fetch data.",
                                "getData",
                                "Definition 2:(string, string[,])",
                                ex.Message,
                                "",
                                Parameters.AppParameters.ErrorLevel.MEDIUM);
                }
     
                return dtResults;
            }
    Desole tout est en anglais c'est parce que je suis pas en france, mon clavier aussi c'est pour cela qu'il n'y a pas d'accent.

    J'ai donc voulu utiliser sa methode pour mon besoin mais cela ne fonctionne pas car il ne close pas non plus son "drResults". Je tombe donc dans le meme probleme.

    Je presume que si je close le "drResults" cela pourrait marcher, je dis "pourrais" car je ne sais pas :

    si le DataTable est un object deconnecte ou non lorsqu'il n'est pas wrapper dans un dataset?

    Ce que j'ai fais jusqu'a present est une methode getDataSet qui me retourne un dataset et en route.

    Mais je ne sais pas si c'est un bonne pratique ou pas, pourriez-vous me le dire?

    Ne me demandez, ce que je pense du code de mon collegue je pourrais vous repondre!!! En plus a la question, la DAL est t'elle terminee reponse OUI, Est t-elle teste reponse OUI, j'ai un seul appele a faire et rien ne marche!!

    Soit dit en passant sa DAL, comporte une classe DBHelper de 1400 lignes (j'aime beaucoups...), 8 autre classe plus ou moins vide (qui me font clairement penser qu'il veut ou voudra faire du mapping object relationnel), une classe du ControlCatolog (une belle classe de 2 malheureuses methodes qui sont celle que j'utilise via une interface et qui appele le helper pour faire le getReader, j'ai d'ailleurs corriger c'est 2 methodes ou le passage de parametre ne marchait pas non plus...)

    Bref mon collegue et moi on va pas etre pote longtemps
    Si quelques avait des excuses pour le sauver, du moins pour m'aider a comprendre pourquoi rien ne marche je suis preneur!
    Ca me verrait chier de le decouper en rondelle si il a des bonnes excuses!!

    Je suis preneur de tout infos.
    Superfly

  4. #4
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Points : 6 334
    Points
    6 334
    Par défaut
    Solution simple : Tu garde le code qui renvoie le DataReader, mais tu supprimes le close. Dans la méthode appelante, tu fais le close après avoir utilisé le reader. ça casse le paradigme du "celui qui ouvre est celui qui ferme", mais ça fonctionne.
    Autre solution, tu gardes le reader mais au lieu de renvoyer le reader, tu renvoie une collection d'objets, au pire, ça peut être une collection de datarow. Au mieux, tu "réflectionnes", et là effectivement ça devient du mapping.
    J'ai déjà vu plusieurs fois la méthode du renvoi de la collection des DataRow du datareader sans renvoyer le datareader en soi.

  5. #5
    Membre du Club
    Inscrit en
    Décembre 2003
    Messages
    102
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 102
    Points : 55
    Points
    55
    Par défaut
    Merci pour ta reponse SaumonAgile.
    J'ai opter pour la solution, t'occuper pas de ton collegue et colle dans sa DAL la methode donc tu as besoin

    Ensuite je reecrirai sa DAL peut etre un jour, ou je serais enerve, ce sera peut etre demain pour l'instant on va essayer de faire fonction ma BLL avec sa DAL et le GUI, car oui forcement on m'a demande un proto.

    Il va de soit que le proto doit marcher avec les donnees reelles et dans le monde reelle en gros un produit fini pour eu!!

    Il va falloir leur expliquer qu'il confonde vitesse et precipitation!!

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    Bref mon collegue et moi on va pas etre pote longtemps
    Méfie-toi, il est peut-être aussi sur ce forum

    Autre solution, tu gardes le reader mais au lieu de renvoyer le reader, tu renvoie une collection d'objets, au pire, ça peut être une collection de datarow.
    Petite restriction quand même, si la requête renvoie une grosse quantité de données tu n'as pas intérêt à faire ça, tu vois pourquoi je suppose... Dans ce cas là tu es à peu près obligé d'utiliser le DataReader, et donc de le fermer dans la fonction appelante.

  7. #7
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 177
    Points : 25 122
    Points
    25 122
    Par défaut
    lu en diagonale, mais tu peux fermer le reader juste avant de l'ouvrir donc au début de ta méthode, plutot quà la fin
    ptete pour ca d'ailleurs que le reader a une proprité IsClosed ...


    if not isclosed, then close

    executereader

  8. #8
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 103
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 103
    Points : 1 561
    Points
    1 561
    Par défaut
    et bien autre proposition... qui ne casse pas la méthode du "celui qui allume la lumière la ferme" comprenez celui qui instancie et ouvre, ferme et libère...

    créer un event handler, qui va recevoir en paramètre non pas un eventargs vide, mais un eventargs dérivé qui contient en paramètre un datareader.

    ta méthode qui "ouvre", avant de faire reader.close(); émet l'évenement en fournissant le reader, puis ferme quand le handler d'évent a fini.

    en réalité ton code n'est pas totalement asynchrone car la fonction appelante est bloquée temps que le processus de lecture, event et fermeture n'est pas achevée puis elle s'arrete... tu sais que quand le handler s'exécute c'est que tu l'a clairement demandé juste avant...

    Donc avec quelques règles de programmation... tu règle ton problème...

    sinon ba autant fermer le reader dans l'appelant... meme si c'est pas propre... ca t'évitera cette tonne de trucs alembiqués (dont suis très frillant, mais on m'a déjà dit que j'était dingue, et j'aurais tendance à le croire donc...)

  9. #9
    Membre du Club
    Inscrit en
    Décembre 2003
    Messages
    102
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 102
    Points : 55
    Points
    55
    Par défaut
    Encore merci pour totu c'est charmant conseil de bidouille
    Mais j'ai opte pour la solution on modifie la DAL.

    Sinon mon collegue n'est pas sur le forum il parle pas francais, je ne suis pas en france moi non plus.

    Bon je vais fermer ce topic, au fait mon collegue ne travaille plus avec moi ce soir

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

Discussions similaires

  1. Réponses: 10
    Dernier message: 28/08/2013, 20h57
  2. Probleme avec la recherche directe de methodes sur une Class (API java.lang.reflect)
    Par CyberChouan dans le forum API standards et tierces
    Réponses: 14
    Dernier message: 25/01/2007, 17h12
  3. [VB.NET] Probleme avec la methode ReadToEnd
    Par Aspic dans le forum VB.NET
    Réponses: 2
    Dernier message: 02/12/2005, 21h10
  4. [Struts] Problème avec la méthode validate
    Par clement42 dans le forum Struts 1
    Réponses: 2
    Dernier message: 09/06/2005, 10h52
  5. probleme avec methode get
    Par Tr@nkill dans le forum ASP
    Réponses: 2
    Dernier message: 12/05/2005, 13h54

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