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

ASP.NET Discussion :

[asp.net2 - c#2 - spring.net] InvalidCastException


Sujet :

ASP.NET

  1. #1
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Mars 2007
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2007
    Messages : 49
    Points : 39
    Points
    39
    Par défaut [asp.net2 - c#2 - spring.net] InvalidCastException
    Salut !

    J'ai un problème de cast dans une requête et je ne vois plus trop quoi faire !
    Dans cette requête, je récupère les demandes client associées à un compte (entreprise) et dans cette requête, je fais la somme du nombre d'intervenants associés à la demande. Le problème intervient sur le type de retour de SUM en SQL. J'ai lu que dans le cas ou un Int32 est passé en paramètre de SUM, le type de retour est Bigint soit Int64.

    J'ai donc paramétré mon code en fonction mais toujours le problème de cast.

    Voici mon code :
    La classe LigneDemande.cs
    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
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
     
    using System;
    using System.Collections.Generic;
    using System.Text;
     
    namespace Gescom07.Core
    {
        // DESCRIPTION : Classe métier représentant une ligne dans la liste des demandes
     
        public class LigneDemande
        {
            #region Attributs
     
            public const string DEMANDE = "ID";
            private Int64 _demande;
     
            public Int64 Demande
            {
                get
                {
                    return _demande;
                }
                set
                {
                    _demande = value;
                }
            }
     
            public const string DATE_SAISIE = "DATE_CREATION";
            private DateTime _dateSaisie;
     
            public DateTime DateSaisie
            {
                get
                {
                    return _dateSaisie;
                }
                set
                {
                    _dateSaisie = value;
                }
            }
     
            public const string COMPTE = "NOM_COMPTE";
            private string _nomCompte;
     
            public string Compte
            {
                get
                {
                    return _nomCompte;
                }
                set
                {
                    _nomCompte = value;
                }
            }
     
            public const string CONTACT = "NOM_CONTACT";
            private string _nomContact;
     
            public string Contact
            {
                get
                {
                    return _nomContact;
                }
                set
                {
                    _nomContact = value;
                }
            }
     
            public const string COMMENTAIRE = "COMMENTAIRE";
            private string _commentaire;
     
            public string Commentaire
            {
                get
                {
                    return _commentaire;
                }
                set
                {
                    _commentaire = value;
                }
            }
     
            public const string NBINTER = "NBINTER";
            private Int64 _nbInter;
     
            public Int64 NbInter
            {
                get
                {
                    return _nbInter;
                }
                set
                {
                    _nbInter = value;
                }
            }
     
            public const string OFFRE = "OFFRE";
            private string _offre;
     
            public string Offre
            {
                get
                {
                    return _offre;
                }
                set
                {
                    _offre = value;
                }
            }
     
            public const string DATE_DEBUT = "DATE_DEBUT_CONTRAT";
            private DateTime _dateDebut;
     
            public DateTime DateDebut
            {
                get
                {
                    return _dateDebut;
                }
                set
                {
                    _dateDebut = value;
                }
            }
     
            #endregion
     
            #region Constructeur
     
            public LigneDemande(){ }
     
            public LigneDemande(Int64 demande, DateTime saisie, string compte, string contact, Int64 nbinter, 
                string offre, DateTime debut)
            {
                this.Demande = demande;
                this.DateSaisie = saisie;
                this.Compte = compte;
                this.Contact = contact;
                this.NbInter = nbinter;
                this.Offre = offre;
                this.DateDebut = debut;
            }
     
            #endregion
        }
    }
    Le code de la méthode ou j'exécute la requête (à la base, avt d'avoir testé le type de retour de SUM) :
    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
    // Récupération des demandes associées à un compte
            public IList<LigneDemande> GetDemandes(Int32 idCompte)
            {
                
                    return AdoTemplate.QueryWithRowMapperDelegate<LigneDemande>(CommandType.Text,
                    "SELECT D.ID, D.DATE_CREATION, CPT.NOM NOM_COMPTE, C.NOM NOM_CONTACT, D.COMMENTAIRE, SUM(R.NB_INTER) NBINTER, O.LIBELLE OFFRE, D.DATE_DEBUT_CONTRAT FROM DEMANDE D, RECHERCHE R, COMPTE CPT, CONTACT C, OFFRE O WHERE CPT.ID = " + idCompte + " AND C.ID_COMPTE = CPT.ID AND D.ID_CONTACT = C.ID AND R.ID_DEMANDE = D.ID AND D.CODE_OFFRE = O.CODE GROUP BY D.ID, D.DATE_CREATION, CPT.NOM, C.NOM, D.COMMENTAIRE, O.LIBELLE, D.DATE_DEBUT_CONTRAT",
                    delegate(IDataReader dataReader, int rowNum)
                    {
                        LigneDemande line = new LigneDemande();
    
                        Type t = dataReader.GetOrdinal(LigneDemande.NBINTER).GetType(); // Type retourné = Int32 alors que c'est censé être Int64
    
                        line.Demande = dataReader.IsDBNull(dataReader.GetOrdinal(LigneDemande.DEMANDE)) ? 0 : dataReader.GetInt64(dataReader.GetOrdinal(LigneDemande.DEMANDE));
                        line.DateSaisie = dataReader.IsDBNull(dataReader.GetOrdinal(LigneDemande.DATE_SAISIE)) ? DateTime.MaxValue : (DateTime)dataReader.GetValue(dataReader.GetOrdinal(LigneDemande.DATE_SAISIE));
                        line.Compte = dataReader.IsDBNull(dataReader.GetOrdinal(LigneDemande.COMPTE)) ? string.Empty : dataReader.GetString(dataReader.GetOrdinal(LigneDemande.COMPTE)).TrimEnd();
                        line.Contact = dataReader.IsDBNull(dataReader.GetOrdinal(LigneDemande.CONTACT)) ? string.Empty : dataReader.GetString(dataReader.GetOrdinal(LigneDemande.CONTACT)).TrimEnd();
                        line.Commentaire = dataReader.IsDBNull(dataReader.GetOrdinal(LigneDemande.COMMENTAIRE)) ? string.Empty : dataReader.GetString(dataReader.GetOrdinal(LigneDemande.COMMENTAIRE)).TrimEnd();
                        line.NbInter = dataReader.IsDBNull(dataReader.GetOrdinal(LigneDemande.NBINTER)) ? 0 : dataReader.GetInt64(dataReader.GetOrdinal(LigneDemande.NBINTER)); // InvalidCastException ici
                        line.Offre = dataReader.IsDBNull(dataReader.GetOrdinal(LigneDemande.OFFRE)) ? string.Empty : dataReader.GetString(dataReader.GetOrdinal(LigneDemande.OFFRE)).TrimEnd();
                        line.DateDebut = dataReader.IsDBNull(dataReader.GetOrdinal(LigneDemande.DATE_DEBUT)) ? DateTime.MaxValue : (DateTime)dataReader.GetValue(dataReader.GetOrdinal(LigneDemande.DATE_DEBUT));
    
                        return line;
                    });
            }
    L'exception intervient à cet endroit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    line.NbInter = dataReader.IsDBNull(dataReader.GetOrdinal(LigneDemande.NBINTER)) ? 0 : dataReader.GetInt64(dataReader.GetOrdinal(LigneDemande.NBINTER));
    Comme le type retourné par SUM semble être Int32 j'ai modifié le code en conséquent mais toujours la même erreur de cast.

    Merci pour votre aide !

  2. #2
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Mars 2007
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2007
    Messages : 49
    Points : 39
    Points
    39
    Par défaut
    Aucune idée sur le problème ?

  3. #3
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Mars 2007
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2007
    Messages : 49
    Points : 39
    Points
    39
    Par défaut
    J'ai trouvé la solution en utilisant une autre méthode qui ma permi d'obtenir le type retourné par SUM dans la cas de ma requête. J'ai eu l'agréable surprise de voir que le type était "Decimal" !!!


    Pour tester le type retourné :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Object o = AdoTemplate.ExecuteScalar(CommandType.Text, "select sum(nbinter) from recherche");
     
    Type t = o.GetType();
    Ensuite pour récupérer la valeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    line.NbInter = dataReader.IsDBNull(dataReader.GetOrdinal(LigneDemande.NBINTER)) ? 0 : Convert.ToInt32(dataReader.GetDecimal(dataReader.GetOrdinal(LigneDemande.NBINTER)));

  4. #4
    Membre à l'essai
    Inscrit en
    Juin 2007
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 15
    Points : 17
    Points
    17
    Par défaut
    Salut,

    Je vois que certains utilisent un vrai framework d'entreprise, ça fait plaisir

    Je voulais juste te donner une astuce pour simplifier ton code et supprimer tout le code repetitif du test sur le IsDbNull :

    Dans la classe AdoTemplate (la version generic ou pas), il existe une propriété qui s'appelle "DataReaderWrapperType" de type "Spring.Data.Support.IDataReaderWrapper" qui te permet d'intercepter les appels au IDataReader courant.
    Spring.Net fournit une implementation pour mapper les valeurs DBNulls vers les valeurs par défaut de chaque type :
    int -> 0
    double -> 0
    boolean -> false
    string -> string.Empty
    etc....

    Lorsque tu configures ton AdoTemplate, il te suffit de spécifier l'implémentation de ton choix :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    <object id="MyAdoTemplate" type="Spring.Data.Generic.AdoTemplate, Spring.Data">
      <property name="DbProvider" ref="MyDbProvider"/>
      <property name="DataReaderWrapperType" value="Spring.Data.Support.NullMappingDataReader, Spring.Data"/>
    </object>
    ton code sera bcp plus lisible, plus besoin de tester le DbNull :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    line.Demande = dataReader.GetInt64(dataReader.GetOrdinal(LigneDemande.DEMANDE));
    line.Compte = dataReader.GetString(dataReader.GetOrdinal(LigneDemande.COMPTE)).TrimEnd();
    Si l'implémentation fournit par Spring ne te plaît pas, tu peux coder ta propre version.

  5. #5
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Mars 2007
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2007
    Messages : 49
    Points : 39
    Points
    39
    Par défaut
    Salut !

    Merci pour ton message. En effet, je trouvais cette syntaxe un peu lourde donc je pense que je vais suivre tes conseils.

    a+

  6. #6
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Mars 2007
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2007
    Messages : 49
    Points : 39
    Points
    39
    Par défaut
    J'ai suivi tes conseils concernant la configuration de l'ado template pour le test sur isDbnull et ça marche nikel !

    Par contre j'ai un souci sur ce test pour une date (type DateTime) !

    J'explique un peu le contexte pour commencer. La date est de type DATE sous Oracle. Je récupère cette date et je la transforme en ShortDateString pour n'avoir que jj/mm/aaaa !

    Voici mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    line.Debut = ((DateTime)dataReader.GetValue(dataReader.GetOrdinal(LigneDemande.DEBUT))).ToShortDateString();
    Le problème est que j'ai inséré un enregistrement avec une date non définie et là ça me génère une exception.

    J'ai fait ça pour gérer l'exception, mais je trouve ça un peu crade :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    try
    {
           line.Debut = ((DateTime)dataReader.GetValue(dataReader.GetOrdinal(LigneDemande.DEBUT))).ToShortDateString();
     }
    catch (Exception)
    {
           line.Debut = "";
    }
    Avec ça pas de problème, dans le cas ou la date est pas définie je mets une chaîne vide dans line.Debut.

    Est-ce qu'il y a moyen de faire autrement ? (pas de try catch à chaque fois qu'une date doit être récupérée)

  7. #7
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Mars 2007
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2007
    Messages : 49
    Points : 39
    Points
    39
    Par défaut
    J'ai trouvé ce que je voulais mais un ptit truc subsiste :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    line.Debut = dataReader.GetDateTime(dataReader.GetOrdinal(LigneDemande.DEBUT)).ToShortDateString();
    En faisant ça, si aucune date n'est renseignée dans la base pour un enregistrement, ça me retourne DateTime.MinValue soit 01/01/0001 et je voudrais que ce soit une chaîne vide à la place.

    Quelqu'un sait si ce la est possible ou non ?

    J'aurais bien mis le code suivant mais je souhaite supprimer le test sur IsDbNull :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    line.Debut = dataReader.IsDBNull(dataReader.GetOrdinal(LigneDemande.DEBUT)) ? String.Empty : ((DateTime)dataReader.GetValue(dataReader.GetOrdinal(LigneDemande.DEBUT))).ToShortDateString();

  8. #8
    Membre à l'essai
    Inscrit en
    Juin 2007
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 15
    Points : 17
    Points
    17
    Par défaut
    Citation Envoyé par alexandre_69
    J'aurais bien mis le code suivant mais je souhaite supprimer le test sur IsDbNull :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    line.Debut = dataReader.IsDBNull(dataReader.GetOrdinal(LigneDemande.DEBUT)) ? String.Empty : ((DateTime)dataReader.GetValue(dataReader.GetOrdinal(LigneDemande.DEBUT))).ToShortDateString();
    tu ne pourras pas gérer cela autrement car ta donnée SQL est dans un champ de type DateTime, et la propriétée de ton object ou tu stockes la valeur est de type string.

    Cela serait possible si tu stockais ta date au format string en base de donnée.

Discussions similaires

  1. [ASP.NET2] [C#] - Connexion à une base SQL en local
    Par skystef dans le forum Accès aux données
    Réponses: 9
    Dernier message: 03/06/2008, 12h24
  2. [ASP.NET2.0] Validation de données
    Par goldeagle dans le forum ASP.NET
    Réponses: 10
    Dernier message: 23/02/2007, 15h04
  3. Réponses: 1
    Dernier message: 24/01/2007, 16h50
  4. [C# ASP.Net2.0] problem avec le type string
    Par wodel dans le forum ASP.NET
    Réponses: 5
    Dernier message: 17/01/2007, 14h03

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