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

Aspose Discussion :

Reflection - Problème d'insertion de données dans des propriétés dynamiques avec Aspose.Cells


Sujet :

Aspose

  1. #1
    Membre averti
    Homme Profil pro
    Apprenti informaticien
    Inscrit en
    Août 2014
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Apprenti informaticien

    Informations forums :
    Inscription : Août 2014
    Messages : 35
    Par défaut Reflection - Problème d'insertion de données dans des propriétés dynamiques avec Aspose.Cells
    Bonjour,

    Je dois mettre à jour dans le cadre de mon stage un programme permettant de récupérer les informations d'une liste d'objets et de l'importer dans la base de données en ajoutant comme fichier source un Excel.

    J'ai récupéré les données dans un datatable grâce à la dll Aspose.Cells. Pour l'insertion des données dans la base de données, j'utilise la dll EntityFramework. J'ai à ma disposition une classe Object contenant les différentes propriétés. Je dois donc insérer les données dans cet objet que j'importe dans la base de données grâce à EntityFramework.

    Comme ces objets ont plus de 140 propriétés, je souhaite utilisé la Reflection et récupéré dynamiquement la propriété de l'objet correspondant à la colonne du Excel. J'arrive à récupérer la PropertyInfo de la propriété voulue, mais mon problème est que je n'arrive pas à rentrer des données à l'intérieur.

    Voici mon code actuel:
    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
    try
                        {
                            foreach (DataRow row in dataTable.Rows) 
    			            {
                                for (int indexHeader = 0; indexHeader < 140; indexHeader++)
                                {
                                    PropertyInfo currentProperty = obj.GetType().GetProperty(Headers[indexHeader]);
    
                                    if (currentProperty != null)
                                    {
                                        // Insertion dans la propriété
                                        
                                    }
                                }
                            }
                        }
                        // ...
    Je boucle en foreach dans mon datatable pour récupérer les lignes de données. Ensuite je boucle en for la liste des propriétés correspondant au colonne du fichier (j'ai du récupérer séparément les en-têtes à cause de la forme du fichier Excel).

    Voilà

    Je vous remercie d'avance du coup de main

    Cordialement
    Faboogy

  2. #2
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2013
    Messages
    93
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2013
    Messages : 93
    Par défaut
    Pour avoir toutes les propriétés d'un type : https://msdn.microsoft.com/fr-fr/lib...vs.110%29.aspx
    Pour avoir une propriété spécifié par son nom d'un type : https://msdn.microsoft.com/fr-fr/lib...vs.110%29.aspx
    Pour set une valeur à une propriété : https://msdn.microsoft.com/fr-fr/lib...vs.110%29.aspx
    Pour get une valeur à une propriété : https://msdn.microsoft.com/fr-fr/lib...vs.110%29.aspx

    Si tu as besoin de plus précis avec ça n'hésite pas ^^

  3. #3
    Membre averti
    Homme Profil pro
    Apprenti informaticien
    Inscrit en
    Août 2014
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Apprenti informaticien

    Informations forums :
    Inscription : Août 2014
    Messages : 35
    Par défaut
    Merci pour les liens, j'avais trouvé ces fonctions, je crois que je dois utiliser setValue, mais je n'arrive pas à la mettre ne place correctement.

    Mon code actuel
    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
    Object obj = new Object();
    
                        try
                        {
                            foreach (DataRow row in dataTable.Rows) 
    			            {
                                for (int indexHeader = 0; indexHeader < 140; indexHeader++)
                                {
                                    PropertyInfo currentProperty = obj.GetType().GetProperty(Headers[indexHeader]);
    
                                    if (currentProperty != null)
                                    {
                                        String type = currentProperty.PropertyType.Name;
    
                                        switch (type)
                                        {
                                            case "Nullable`1":
                                                //currentProperty.SetValue(obj, int.Parse(row[indexHeader].ToString()), new object[] { int.Parse(row[indexHeader].ToString()) });
                                                break;
                                            case "Int32":
                                                currentProperty.SetValue(obj, int.Parse(row[indexHeader].ToString()), new object[] { int.Parse(row[indexHeader].ToString()) });
                                                break;
                                            case "Boolean":
                                                currentProperty.SetValue(obj, Convert.ToBoolean(row[indexHeader].ToString()), new object[] { int.Parse(row[indexHeader].ToString()) });
                                                break;
                                            default:
                                                currentProperty.SetValue(obj,row[indexHeader].ToString(),  new object[] { row[indexHeader].ToString() });
                                                break;
                                        }
                                    }
                                }
                            }
    Il me génère cette erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [System.Reflection.TargetParameterCountException] = {"Nombre de paramètres incorrects."}
    Au cas où, mes propriétés sont de cette forme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
            public int IdObject { get; set; }
            public Nullable<int> IdFM { get; set; }
            public int InvNr { get; set; }
            public Nullable<int> ObjectNr { get; set; }
            public string Character { get; set; }
            public string Object1 { get; set; }
    Edit:
    Je n'ai pas accès au constructeur PropertyInfo.SetValue, méthode (Object, Object), mais soit à PropertyInfo.SetValue, méthode (Object, Object, Object[]), soit à PropertyInfo.SetValue, méthode (Object, Object, BindingFlags, Binder, Object[], System.Globalization.CultureInfo)

  4. #4
    Membre averti
    Homme Profil pro
    Apprenti informaticien
    Inscrit en
    Août 2014
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Apprenti informaticien

    Informations forums :
    Inscription : Août 2014
    Messages : 35
    Par défaut
    Ma propriété n'a en fait pas de paramètre alors j'ai changé mon code:
    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
    Object obj = new Object();
                        
                        try
                        {
                            foreach (DataRow row in dataTable.Rows) 
    			            {
                                for (int indexHeader = 0; indexHeader < 140; indexHeader++)
                                {
                                    PropertyInfo currentProperty = obj.GetType().GetProperty(Headers[indexHeader]);
    
                                    if (currentProperty != null)
                                    {
                                        String type = currentProperty.PropertyType.Name;
                                        
                                        switch (type)
                                        {
                                            case "Nullable`1":
                                                //currentProperty.SetValue(obj, int.Parse(row[indexHeader].ToString()), null);
                                                break;
                                            case "Int32":
                                                currentProperty.SetValue(obj, int.Parse(row[indexHeader].ToString()), null);
                                                break;
                                            case "Boolean":
                                                currentProperty.SetValue(obj, Convert.ToBoolean(row[indexHeader].ToString()), null);
                                                break;
                                            default:
                                                currentProperty.SetValue(obj,row[indexHeader].ToString(),  null);
                                                break;
                                        }
                                    }
                                }
                            }
                        }
    Il ne me retourne plus aucune erreur, à part 2-3 valeurs parsemées, elles restent toutes à null et celles qui sont modifiés sont parfois des string, parfois des int et parfois des bool.

  5. #5
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2013
    Messages
    93
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2013
    Messages : 93
    Par défaut
    Le soucis c'est que je comprends pas trop l'intérêt :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    PropertyInfo currentProperty = obj.GetType().GetProperty(Headers[indexHeader]);
    Cela récupère les propriétés avec un nom précis, d'un objet de Type Object.

    Tu tapes toujours sur le même objet au final donc tes valeurs seront remplacées à l'infini tu sauvegarderas que les dernières.

    Je vais te donner un exemple.

    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
    static void Main(string[] args)
            {
                Donnee don = new Donnee(5, "Bonjour");
                PropertyInfo infoProprieteId = don.GetType().GetProperty("Id");
                Console.WriteLine("Retourne la value de la propriété Id de l'objet don : " + infoProprieteId.GetValue(don).ToString()); 
                infoProprieteId.SetValue(don, 10); // Id vaut 10 maintenant
                Console.WriteLine("Retourne la nouvelle value de la propriété Id de l'objet don :" + infoProprieteId.GetValue(don).ToString()); //Retourne la value de la propriété Id de l'objet don
                List <Donnee> list = new List<Donnee>();
                for(int i = 0; i < 10; i++)
                    list.Add((Donnee)Activator.CreateInstance(don.GetType(), i, "Text")); //Ajoute dans ma liste une instance de l'objet Donnee avec paramètre
                foreach (Donnee done in list)
                    Console.WriteLine(done.Id + " " + done.Text);
                Console.Read();
            }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class Donnee
        {
            public int Id { get; set; }
            public string Text { get; set; }
    
            public Donnee(int id, string text)
            {
                this.Id = id;
                this.Text = text;
            }
        }


    PS : Si tu pouvais mettre des commentaire à chaque ligne de code pour montrer quelle est ton intention de faire à telle ligne par exemple.

  6. #6
    Membre averti
    Homme Profil pro
    Apprenti informaticien
    Inscrit en
    Août 2014
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Apprenti informaticien

    Informations forums :
    Inscription : Août 2014
    Messages : 35
    Par défaut
    Pour enregistrer un objet, avec EntityFramework, il suffit de faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    db.Objects.Add(obj);
    db.SaveChanges();
    Il me suffit donc d'effectuer ces deux lignes à la fin du foreach pour enregistrer dans la base de données. Je ne les ai pas encore mises pour éviter de risquer d'entrer des données par inadvertance dans la base de données et trop la polluer.

    Voici mon code commenté:
    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
                        Object obj = new Object();
                        
                        try
                        {
                            // Boucle les lignes dans les données provenant du excel
                            foreach (DataRow row in dataTable.Rows) 
    			            {
                                // Boucle les propriétés (qui correspondent au colonne du excel)
                                for (int indexHeader = 0; indexHeader < 140; indexHeader++)
                                {
                                    // Récupère la propriété correspondant à la cellule
                                    PropertyInfo currentProperty = obj.GetType().GetProperty(Headers[indexHeader]);
    
                                    // Test si la propriété existe
                                    // Certaines colonnes ne correspondent pas directement à une propriété à cause des clés étrangères
                                    if (currentProperty != null)
                                    {
                                        // Récupère le type de la valeur
                                        String type = currentProperty.PropertyType.Name;
                                        
                                        // Test le type et fait le code en conséquence
                                        // Cela servira par la suite à faire des tests sur les valeurs et à enregistrer des logs
                                        switch (type)
                                        {
                                            case "Nullable`1":
                                                //currentProperty.SetValue(obj, int.Parse(row[indexHeader].ToString()), null);
                                                break;
                                            case "Int32":
                                                currentProperty.SetValue(obj, int.Parse(row[indexHeader].ToString()), null);
                                                break;
                                            case "Boolean":
                                                currentProperty.SetValue(obj, Convert.ToBoolean(row[indexHeader].ToString()), null);
                                                break;
                                            default:
                                                currentProperty.SetValue(obj,row[indexHeader].ToString(),  null);
                                                break;
                                        }
                                    }
                                }
    
                                //Enregistrement de la ligne
                                //db.Objects.Add(obj);
                                //db.SaveChanges;
                            }

  7. #7
    Membre averti
    Homme Profil pro
    Apprenti informaticien
    Inscrit en
    Août 2014
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Apprenti informaticien

    Informations forums :
    Inscription : Août 2014
    Messages : 35
    Par défaut
    Alors j'ai trouvé l'erreur se trouvait au niveau du switch. Je devais d'abord parser en int avant de convertir en booléen. Il me rester plus qu' à trouver comment convertir en Nullable<int> un string.
    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
             switch (type)
             {
                      case "Nullable`1":
                              //currentProperty.SetValue(obj, int.Parse(row[indexHeader].ToString()), null);
                              break;
                      case "Int32":
                             currentProperty.SetValue(obj, int.Parse(row[indexHeader].ToString()), null);
                             break;
                      case "Boolean":
                             currentProperty.SetValue(obj, Convert.ToBoolean(int.Parse(row[indexHeader].ToString())), null);
                             break;
                      default:
                             currentProperty.SetValue(obj,row[indexHeader].ToString(),  null);
                             break;
              }

  8. #8
    Membre averti
    Homme Profil pro
    Apprenti informaticien
    Inscrit en
    Août 2014
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Apprenti informaticien

    Informations forums :
    Inscription : Août 2014
    Messages : 35
    Par défaut
    Alors c'est bon j'ai réussi ma fonction. Il ne me reste plus qu'à intégrer les tests pour la saisie du client. Voici le code:
    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
                        Object obj = new Object();
                        
                        try
                        {
                            // Boucle les lignes dans les données provenant du excel
                            foreach (DataRow row in dataTable.Rows) 
    			            {
                                // Boucle les propriétés (qui correspondent au colonne du excel)
                                for (int indexHeader = 0; indexHeader < 140; indexHeader++)
                                {
                                    // Récupère la propriété correspondant à la cellule
                                    PropertyInfo currentProperty = obj.GetType().GetProperty(Headers[indexHeader]);
    
                                    // Test si la propriété existe
                                    // Certaines colonnes ne correspondent pas directement à une propriété à cause des clés étrangères
                                    if (currentProperty != null)
                                    {
                                        // Récupère le type de la valeur
                                        String type = currentProperty.PropertyType.Name;
    
                                        int tryInt = 0;
                                        Decimal tryDecimal = 0;
    
                                        // Test le type et fait le code en conséquence
                                        // Cela servira par la suite à faire des tests sur les valeurs et à enregistrer des logs
                                        switch (type)
                                        {
                                            case "Nullable`1":
    
                                                try
                                                {
                                                    Int32.TryParse(row[indexHeader].ToString(), out tryInt);
                                                    if (tryInt != 0)
                                                    {
                                                        currentProperty.SetValue(obj, tryInt, null);
                                                    }
                                                }
                                                catch
                                                {
                                                    try
                                                    {
                                                        Decimal.TryParse(row[indexHeader].ToString(), out tryDecimal);
                                                        if (tryDecimal != 0)
                                                        {
                                                            currentProperty.SetValue(obj, tryDecimal, null);
                                                        } 
                                                    }
                                                    catch
                                                    { }
                                                }
    
                                                break;
                                            case "Int32":
                                                currentProperty.SetValue(obj, int.Parse(row[indexHeader].ToString()), null);
                                                break;
                                            case "Boolean":
                                                currentProperty.SetValue(obj, Convert.ToBoolean(int.Parse(row[indexHeader].ToString())), null);
                                                break;
                                            default:
                                                currentProperty.SetValue(obj,row[indexHeader].ToString(),  null);
                                                break;
                                        }
                                    }
                                }
    
                                //Enregistrement de la ligne
                                //db.Objects.Add(obj);
                                //db.SaveChanges();
                            }
    Merci de ton coup de main Kangourex.

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

Discussions similaires

  1. [Oracle] problème d'insertion de données dans une table sous oracle
    Par Zombiman dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 27/05/2009, 14h58
  2. problème d'insertion de données dans table
    Par loic20h28 dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 31/01/2008, 17h26
  3. problème d'insertion de données dans une map
    Par kifouillou dans le forum Collection et Stream
    Réponses: 11
    Dernier message: 21/02/2007, 10h10
  4. [MySQL] Problème d'insertion de données dans ma base
    Par kilkikou dans le forum PHP & Base de données
    Réponses: 17
    Dernier message: 24/01/2007, 10h15
  5. [MySQL] Problème d'insertion de données dans table d'associations
    Par Yukhaa dans le forum PHP & Base de données
    Réponses: 13
    Dernier message: 07/02/2006, 17h10

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