C# - LinqToExcel - Map type complexe

Utilisateur anonyme - 16 mai 2016 à 23:08
Whismeril Messages postés 19025 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 avril 2024 - 17 mai 2016 à 23:47
Bonjour,

J'ai deux classes :

public class Customer
{
    public string FirstName { get; set; }
 
    public string LastName { get; set; }
 
    public Count Count { get; set; }
}
 
public class Count
{
    public string Property1 { get; set; }
 
    public int Number { get; set; }
}



Et un fichier excel :



Je veux créer une instance de ma classe depuis mon fichier excel.

J'utilise LinqToExcel Library (https://github.com/paulyoder/LinqToExcel) :

var excelFile = new ExcelQueryFactory(pathToExcelFile);
 
excelFile.AddMapping<Customer>(x => x.Count.Number, "Number");
 
var data = excelFile.Worksheet<Customer>(sheetName).Select(x => x).ToArray();



Mais la propriété Number est null malgré le AddMapping que j'ai rajouté

Comment faire ?

Merci

6 réponses

Whismeril Messages postés 19025 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 avril 2024 656
17 mai 2016 à 20:38
Bonsoir

comme LinqToExcel m'interresse aussi et même si je n'avais pas encore testé, je me suis penché sur ton problème.

Je pense que le happer ne te permets que de changer le nom d'un champ d'un type de base, pas de créer une instance d'une autre classe.
Pour étayer mon hypothèse, si on définit Count comme étant un int, ça marche.

J'ai donc trouvé une astuce, pas très propre, pour contourner le problème.

    public class Customer
    {
        public string FirstName { get; set; }

        public string LastName { get; set; }

        public Count Count { get; set; }

        private int monCompte;
        public int MonCompte
        {
            set
            {
                monCompte = value;
                Count = new Count { Number = monCompte, Property1 = "test" };
            }

            get { return monCompte; }
        }


        public static Customer[] LireFichier(string Filename)
        {
            ExcelQueryFactory excelFile = new ExcelQueryFactory(Filename);

            excelFile.AddMapping<Customer>(x => x.MonCompte, "Number");

            return (from x in excelFile.Worksheet<Customer>("Feuil1")
                    select x).ToArray();


        }
    }

0
Utilisateur anonyme
17 mai 2016 à 20:46
Merci pour ta réponse.

Passer par un propriété intermédiaire ne m'interrese pas. Si je dois faire ça pour toutes mes sous classe je suis mal barré....
0
Whismeril Messages postés 19025 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 avril 2024 656
17 mai 2016 à 21:17
En continuant, à gratter, j'ai vu qu'il y a une surcharge à la méthode AddMapping, permettant de spécifier une transformation.
Et aussi une méthode AddTransformation, dont la description contient un exemple de syntaxe.

Que l'on retrouve dans le code source
        /// <summary>
        /// Transforms a cell value in the spreadsheet to the desired property value
        /// </summary>
        /// <typeparam name="TSheetData">Class type to return row data as</typeparam>
        /// <param name="property">Class property value to transform</param>
        /// <param name="transformation">Lambda expression that transforms the original string value to the desired property value</param>
        /// <example>
        /// AddTransformation{Person}(p => p.IsActive, x => x == "Y");
        /// AddTransformation{Person}(p => p.IsYoung, x => DateTime.Parse(x) > new DateTime(2000, 1, 1));
        /// </example>



Et cela donne
        public string FirstName { get; set; }

        public string LastName { get; set; }

        public Count Count { get; set; }

        public static Customer[] LireFichier(string Filename)
        {
            ExcelQueryFactory excelFile = new ExcelQueryFactory(Filename);

            excelFile.AddMapping<Customer>(x => x.Count, "Number",y =>  new Count { Number = Convert.ToInt32(y) });

            return (from x in excelFile.Worksheet<Customer>("Feuil1")
                    select x).ToArray();


        }
    }

0
Utilisateur anonyme
17 mai 2016 à 21:20
Merci énormément pour ta réponse et le travail que tu as fourni
pour m'aider !
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Utilisateur anonyme
17 mai 2016 à 21:24
Et donc comment faire pour mapper à la fois Number et Property1 ?
Merci encore
0
Whismeril Messages postés 19025 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 avril 2024 656
17 mai 2016 à 21:43
Sais pas.
Il faut commencer par expliquer d'où il sort.
0
Utilisateur anonyme
17 mai 2016 à 21:44
De l'excel egalement, une des colonnes
0
Whismeril Messages postés 19025 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 19 avril 2024 656
17 mai 2016 à 23:47
A priori la transformation ne concerne qu'une cellule.
J'ai donc essayé d'ajouter un Mapper, en me disant qu'une fois l'instance crée on pourrait y ajouter des données, comme ça
            excelFile.AddMapping<Customer>(x => x.Count, "Number",y =>  new Count { Number = Convert.ToInt32(y) });
            excelFile.AddMapping<Customer>(x => x.Count.Property1, "Property1");



Mais ça ne marche pas, la solution de la propriété intermédiaire me parait la seule pour l'instant.

Pour que ce soit plus propre que ce que j'ai fait plus haut, et surtout pour que le reste du programme n'est accès qu'à ce qui est nécessaire, j'ai dérivé ta classe, mis les propriétés intermédiaires et retourné un tableau de la classe Customer

    public class Customer
    {
        public string FirstName { get; set; }

        public string LastName { get; set; }

        public Count Count { get; set; }

        public static Customer[] LireFichier(string Filename)
        {
            ExcelQueryFactory excelFile = new ExcelQueryFactory(Filename);

            excelFile.AddMapping<Customer>(x => x.Count, "Number",y =>  new Count { Number = Convert.ToInt32(y) });           

            return (from x in excelFile.Worksheet<ImportCustomer>("Feuil1")
                    select x.SetProperty1()).ToArray();
        }


    }

    class ImportCustomer:Customer
    {

        private string property1;

        public string Property1
        {
            get { return property1; }
            set { property1 = value; }
        }
        
        public Customer SetProperty1()
        {
            this.Count.Property1 = this.Property1;
            return (Customer)this;
        }
        
    }


J'ai été obligé d'ajouter la méthode SetProperty1, car directement à la propriété l'instance de Count n'était pas crée.
Cela peut venir de l'évaluation différée des requêtes Linq
https://msdn.microsoft.com/fr-fr/library/bb943859.aspx
Ou d'un je ne sais quoi de la lib LinqToExcel.

0
Rejoignez-nous