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

  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur Full-stack
    Inscrit en
    Novembre 2010
    Messages
    372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Développeur Full-stack

    Informations forums :
    Inscription : Novembre 2010
    Messages : 372
    Points : 489
    Points
    489
    Par défaut "Impossible d'effectuer un cast d'un objet de type '{0}' en type 'System.Collections.Generic.IEnumerable`1[{1}
    Bonjour à tous,

    J'ai une fonction avec une énumération en paramètre qui me retourne un DataTable après une série d'itération. Le problème est que à chaque tentative, un problème de CAST surgit:

    Voici ma fonction:
    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
     
            public static DataTable GetLINQToDataTable<t>(IEnumerable<t>  varlist)
            {
                DataTable dtReturn = new DataTable();
     
                // column names 
                PropertyInfo[] oProps = null;
     
                if (varlist == null) return dtReturn;
     
                foreach (IEnumerable<t> rec in varlist)
                {
     
                    if (oProps == null)
                    {
                        foreach (PropertyInfo pi in oProps)
                        {
                            Type colType = pi.PropertyType;
                            if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>)))
                            {
                                colType = colType.GetGenericArguments()[0];
                            }
     
                            dtReturn.Columns.Add(new DataColumn(pi.Name, colType));
     
                        }
                    }
     
                    DataRow dr = dtReturn.NewRow();
     
                    foreach (PropertyInfo pi in oProps)
                    {
                        dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue(rec, null);
                    }
     
                }
     
                return dtReturn;
            }
    J'appelle cette fonction comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
                        IEnumerable<Person > listePerson  = (from oPerson in ContexteDAO.ContexteDonnees.Persons
                        where oPerson .CodeCompagnie == aCodeCompagnie
                        select oPerson ).ToList();
     
                            DataTable dt = new DataTable();
     
                            dt = LINQToDataTable(listePerson);
    Lors du débogage, le programme saute au niveau du :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    foreach (IEnumerable<t> rec in varlist)
    Merci de me donner un coup de main.

  2. #2
    Membre éprouvé Avatar de worm83
    Homme Profil pro
    Architecte logiciel
    Inscrit en
    Février 2010
    Messages
    459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte logiciel
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2010
    Messages : 459
    Points : 1 118
    Points
    1 118
    Par défaut
    Bon je suis fatigué, ok, mais ton programme compile ????

    Le bon code serais plutôt :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    foreach t rec in varlist)
    {
     
    }

  3. #3
    Membre expérimenté
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2005
    Messages
    562
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2005
    Messages : 562
    Points : 1 511
    Points
    1 511
    Par défaut
    Bonjour,

    Remplace
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    foreach (IEnumerable<t> rec in varlist)
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    foreach (t rec in varlist)
    De plus le reste de ta méthode est à revoir je pense, la partie =>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    if (oProps == null)
    {
        foreach (PropertyInfo pi in oProps)
        {...}
    }
    n'est pas cohérente et provoquera sans doute un nullReferenceException.

    Bon code.

  4. #4
    Membre confirmé
    Homme Profil pro
    Développeur Full-stack
    Inscrit en
    Novembre 2010
    Messages
    372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Développeur Full-stack

    Informations forums :
    Inscription : Novembre 2010
    Messages : 372
    Points : 489
    Points
    489
    Par défaut
    Citation Envoyé par J@ckHerror Voir le message
    Bonjour,



    De plus le reste de ta méthode est à revoir je pense, la partie =>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    if (oProps == null)
    {
        foreach (PropertyInfo pi in oProps)
        {...}
    }
    n'est pas cohérente et provoquera sans doute un nullReferenceException.

    Bon code.
    Merci pour vos réponses, vous aviez vu juste. Le programme compile correctement, mais l'exécution il y a problème. En modifiant le code comme demandé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    foreach (t rec in varlist)
    , certes il n'y a plus de blocage mais une exception de nullité est levée à ce niveau:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    if (oProps == null)
    {
        foreach (PropertyInfo pi in oProps)
        {...}
    }
    Au fait mon problème est de charger ma liste que voici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
                       IEnumerable<Person > listePerson  = (from oPerson in ContexteDAO.ContexteDonnees.Persons
                        where oPerson .CodeCompagnie == aCodeCompagnie
                        select oPerson ).ToList();
    ou une quelconque dans une datatable pour alimenter un état crystal report, mais ma fonction ne peut faire l'affaire. Auriez-vous une idée?

    Merci d'avance.

  5. #5
    Membre expérimenté
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2005
    Messages
    562
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2005
    Messages : 562
    Points : 1 511
    Points
    1 511
    Par défaut Convertir une IEnumerable<T> en DataTable.
    Bonjour,

    Le but de votre méthode est donc de convertir une IEnumerable<T> en DataTable.
    Votre méthode est incomplète, oProps est initialisé à null et n'est jamais affecté ensuite, c'est la raison de NullReferenceException.
    Pour obtenir la liste des properties d'un Type =>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    System.Reflection.PropertyInfo[] oProps = typeof(T).GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic |
                System.Reflection.BindingFlags.Public);
    Doc MSDN

    Il ne devrait plus que rester cette petite coquille
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if (oProps != null)
    {...}
    Bonne journée
    et bon code.

    J@ck

  6. #6
    Membre confirmé
    Homme Profil pro
    Développeur Full-stack
    Inscrit en
    Novembre 2010
    Messages
    372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Développeur Full-stack

    Informations forums :
    Inscription : Novembre 2010
    Messages : 372
    Points : 489
    Points
    489
    Par défaut
    Bonjour,

    L'itération saute l'entrée de la seconde boucle foreach, ligne 94 (voir image)


    Nom : 28-08-2015 08-12-46.png
Affichages : 2068
Taille : 108,8 Ko.

    Après les modifications sus recommandées un avertissement apparait en bas de page.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Avertissement	1	Possibilité d'instruction vide erronée

  7. #7
    Membre expérimenté
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2005
    Messages
    562
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2005
    Messages : 562
    Points : 1 511
    Points
    1 511
    Par défaut
    Vous ne faite pas les bonnes choses aux bons endroits .

    il vous faut initialiser oProps comme je vous l'ai montré, puis tester si il est null ou non, et si il n'est pas null on le parcours pour créer les columns.
    Puis une fois les columns crées il vous faudra reparcourir votre IEnumerable<t> pour ajouter un ligne à la DataTable par élément de l'énumération.

    Tout ceci devrait être assez simple, vous avez déjà les principales étapes, mais si vous rencontrez des problèmes faites signe ...

    J@ck.

  8. #8
    Membre confirmé
    Homme Profil pro
    Développeur Full-stack
    Inscrit en
    Novembre 2010
    Messages
    372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Développeur Full-stack

    Informations forums :
    Inscription : Novembre 2010
    Messages : 372
    Points : 489
    Points
    489
    Par défaut
    Merci d'avance. J'ai modifié le code comme souhaité, il devient ce ceci:

    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
     
            public static DataTable LINQToDataTable<t>(IEnumerable<t> varlist)
            {
                DataTable dtReturn = new DataTable();
     
     
                PropertyInfo[] oProps = typeof(t).GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic |
                System.Reflection.BindingFlags.Public);
     
                if (varlist == null) return dtReturn;
     
                foreach (t rec in varlist)
                {
     
                    if (oProps != null)
                    {
                        foreach (PropertyInfo pi in oProps)
                        {
                            Type colType = pi.PropertyType;
                            if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>)))
                            {
                                colType = colType.GetGenericArguments()[0];
                            }
     
                            dtReturn.Columns.Add(new DataColumn(pi.Name, colType));
     
                        }
                    }
     
                    DataRow dr = dtReturn.NewRow();
     
                    foreach (PropertyInfo pi in oProps)
                    {
     
                        dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue(rec, null);
                    }
     
                }
     
                return dtReturn;
            }
    Le seul hic, est que en la dernière boucle foreach saute à la seconde itération avec cette exception:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Une colonne nommée 'MaColonne' appartient déjà à ce DataTable."}
    Encore une fois merci pour le coup de main.

  9. #9
    Membre expérimenté
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2005
    Messages
    562
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2005
    Messages : 562
    Points : 1 511
    Points
    1 511
    Par défaut
    C'est normal, car à chaque tour du premier foreach on va ajouter des Colomns (exécuter en mode debug-pas à pas et vous vous en rendrez compte) et ce n'est pas ce que l'on souhaite...
    Ce que l'on veut c'est créer une et une seule fois les entêtes de colonnes, puis autant de ligne qu'il y a d'éléments dans notre énumération.

    Pour cela plusieurs possibilités, la plus simple serait de mettre oProps à null juste après la création de toutes les Columns, en gros juste avant le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    		DataRow dr = dtReturn.NewRow();
    Pour ma part, et pour plus de lisibilité j'aurais séparé l'étape de création des Columns et l'étape de création des Rows, chacune dans un foreach, le premier sur oProps et le second sur varlist ... à vous de voir.

    J@ck.

  10. #10
    Membre confirmé
    Homme Profil pro
    Développeur Full-stack
    Inscrit en
    Novembre 2010
    Messages
    372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Développeur Full-stack

    Informations forums :
    Inscription : Novembre 2010
    Messages : 372
    Points : 489
    Points
    489
    Par défaut
    Citation Envoyé par J@ckHerror Voir le message
    ...
    Pour cela plusieurs possibilités, la plus simple serait de mettre oProps à null juste après la création de toutes les Columns, en gros juste avant le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    		DataRow dr = dtReturn.NewRow();
    Pour ma part, et pour plus de lisibilité j'aurais séparé l'étape de création des Columns et l'étape de création des Rows, chacune dans un foreach, le premier sur oProps et le second sur varlist ... à vous de voir.

    J@ck.
    Vraiment un exemple de code pourrait mieux m'éclaircir et sera le bienvenu . J'éssaie d'optimiser le code comme je peux, mais les exceptions persistent. Avec oProps = null, il y a une exception de nullité. Et en remontant d'une accolade "}" le code suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    DataRow dr = dtReturn.NewRow();
     
     
                    foreach (PropertyInfo pi in oProps)
                    {
     
                        dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue(rec, null);
                    }
    J'ai ce message:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     "La colonne ''MaSecondeColonne" n''existe pas dans la table."

    Merci.

  11. #11
    Membre expérimenté
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2005
    Messages
    562
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2005
    Messages : 562
    Points : 1 511
    Points
    1 511
    Par défaut
    Si c'est ce que vous voulez, la voici, je vous laisse l'analyser et comparer avec la votre.
    Pour les indications vous pouvez en trouver ici
    Cependant vous ne progresserez qu'en comprenant les exceptions et comment passer outre, du code tout fait n'est qu'une solution à court terme.

    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
     
                PropertyInfo[] properties = typeof(T).GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic |
                System.Reflection.BindingFlags.Public);
     
                DataTable table = new DataTable();
                foreach (System.Reflection.PropertyInfo prop in properties.ToList())
                {
                    table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
                }
     
                foreach (T item in data)
                {
                    DataRow row = table.NewRow();
                    foreach (System.Reflection.PropertyInfo prop in properties)
                        row[prop.Name] = prop.GetValue(item, null) ?? DBNull.Value;
                    table.Rows.Add(row);
                }
                return table;
    Bonne journée et bon code.
    J@ck

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 07/05/2015, 17h42
  2. Réponses: 4
    Dernier message: 10/05/2011, 11h55
  3. Réponses: 7
    Dernier message: 26/04/2011, 18h00
  4. Réponses: 0
    Dernier message: 13/03/2010, 10h25
  5. Réponses: 2
    Dernier message: 06/03/2007, 19h38

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