Remplir proprités d'une classe à partir des items list<list>>

dodo7263 Messages postés 614 Date d'inscription mercredi 10 septembre 2008 Statut Membre Dernière intervention 9 février 2017 - 9 févr. 2017 à 20:43
Whismeril Messages postés 19024 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 18 avril 2024 - 10 févr. 2017 à 13:09
Bonjour,
Alors voila :
Disons que j'ai une classe avec 2 propriétés :

class dataTable
{
private string m_param1;

private string m_param2;

public string Param1
{
get { return m_param1; }
set { m_param1 = value; }

}

public string Param2
{
get { return m_param2; }
set { m_param2 = value; }

}

public dataTable() { }

public dataTable(List<List<string>> maListe)
{
foreach ()
{
foreach ()
{
m_param1 = ; // item correct correspondant à param1
m_param2 = ; // item correct correspondant à param2

}
}


}
}

Dans le constructeur de cette classe je cherche à remplir mes propriétés avec la double liste en paramètre. Cette liste contient des infos d'un fichier CSV. Je sais comment accéder au items de ma double liste en revanche à cet endroit je ne sais pas si la valeur de l'item[0] correspond à mon param1 ou mon param2.
Donc voici la question simple comment pourrais faire pour en fait identifier sans ambiguïté les items de ma double liste pour pouvoir remplir mes propriétés correctement ?
Merci à ceux qui prendront le temps de lire.
@pluche
SD

1 réponse

Whismeril Messages postés 19024 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 18 avril 2024 656
9 févr. 2017 à 21:20
Bonsoir

d'abord une petite remarque, DataTable est déjà une classe du Framework, ce serait p'tet judicieux de trouver un autre nom.

Quand tu dis que tu ne sais pas si l'item[0] correspond à param1, cela veut dire que les colonnes de ton csv ne sont pas forcément toujours dans le même ordre?
Y'a t il une ligne d'entête?

En plus ce que montre ton code c'est d'une liste de liste (issue d'un csv) tu fais une seule instance puisque tu passes par le constructeur.
Ton but serait-il plutot d'avoir une collection de données (plus en relation avec le nom dataBase)?

0
dodo7263 Messages postés 614 Date d'inscription mercredi 10 septembre 2008 Statut Membre Dernière intervention 9 février 2017 6
9 févr. 2017 à 22:05
Bonsoir wishmeril,

Oui en effet le nom de la classe est mal choisi. C'est pour l'exemple.
En revanche tu as raison mon fichier csv ne sera pas forcement dans le même ordre d'un jour à l'autre mais avec toujours les mêmes données. il y a bien une ligne d'entête mais je ne m'en préoccupe pas.

En fait j’essaie d’insérer dans une table cette fameuse liste de liste pour ne faire qu'un seul appel SQL. Donc en y réfléchissant depuis tout à l'heure je viens de me rendre compte que mon exemple ne fonctionnera pas car ma double liste lorsqu'elle contiendra plusieurs liste je ne garderai que les derniers items de la dernière liste. Donc oui je pense que la collection de données serait plus judicieux ici.
0
Whismeril Messages postés 19024 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 18 avril 2024 656
9 févr. 2017 à 22:21
Je ne voies pas le rapport avec l'appel sql...

Tu ne te préoccupes pas de la ligne d'entête soit, alors par quel miracle espère tu savoir quel colonne est placée ou?
0
dodo7263 Messages postés 614 Date d'inscription mercredi 10 septembre 2008 Statut Membre Dernière intervention 9 février 2017 6
9 févr. 2017 à 23:21
oui c'est un peu incompréhensible, je comprends. Moi même j'ai un peu de mal. Je vais essayer de t'expliquer plus en détail. En fait il y a bien une ligne d'en tête mais qui ne décrit rien du tout si ce n'est le nom du fichier. c'est juste une entete pour dire qu'il y en a une.
Un exemple de mon fichier csv ci dessous :

380;111111111111111111;ET;02-02-2017;Desactive;
380;2222222222222222;EC;02-02-2017;liste noire;
380;3333333333333333;AB;02-02-2017;Desactive;
550;4444444444444444;ET;02-02-2017;Desactive;
550;5555555555555555;ET;02-02-2017;Desactive;


Jusqu'a présent je lis mon csv et chaque champ d'une ligne de ce fichier (séparateur ;) est mis dans ma liste de liste. Mon traitement lit ce fichier csv tant que le premier champ a la même valeur (380). Des qu'il trouve une valeur différente (550) on insère les lignes lues dans une table et on reprend à la ligne où on s'était arrêté. Mais on m'a demandé de ne pas faire un appel par ligne lue. On m'a demandé d'insérer les 3 premières lignes (ici dans mon exemple) en une seule fois avec une seule requête. Cette requête est dans une procStock a laquelle je passe les paramètres et les valeurs qui correspondent aux champs du fichier csv.

voila pour plus de détail. Je ne sais pas si ça peut t'aider mais je viens d'avoir une idée. Si je peux passer en paramètre de ma procstock 3 listes qui correspondent à une ligne du csv je peux peut être m'en sortir avec une requete de ce genre :
INSERT INTO `laTable` (`champ1`,` champ2`, `champ...`)
VALUES
('valeur1', 'valeur2', 'valeur...'),
('valeur1', 'valeur2', 'valeur...');


qu'en penses tu ? Bonne ou mauvaise idée ?
0
Whismeril Messages postés 19024 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 18 avril 2024 656
Modifié par Whismeril le 10/02/2017 à 12:10
Les bases de données c'est pas mon dada.... donc sur cette partie là je ne te serai pas d'une grande aide.

Ca ne m'explique pas comment on choisi quelle colonne du csv correspond à quel champ de la classe.
S'il faut reconnaitre ce qui est écrit tu peux tenter les regex.

Puisque tu dis que le premier numéro est une référence, je pars du principe qu'il est toujours au début.

Voilà un début de piste, mais je bloque sur le commentaire, pour l'instant ça me capture soit le grand nombre, soit les lettres.

using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;

namespace Test_divers_Csharp
{
    class LaClasseADodo
    {
        public int Reference { get; set; }

        public Int64 GrandNumero { get; set; }

        public string Lettres { get; set; }

        public string Commentaire { get; set; }

        public DateTime Date { get; set; }

        public static void ImportCsv(string Filename)
        {
            foreach (string ligne in File.ReadAllLines(Filename).Skip(1))//le skip c'est pour virer la ligne d'entête
            {
                LaClasseADodo nouveau = new LaClasseADodo();
                nouveau.Reference = Convert.ToInt32(ligne.Split(';')[0]);

                Match m = Regex.Match(ligne, @";(?<numero>\d+);");
                if (m.Success)
                    nouveau.GrandNumero =  Convert.ToInt64(m.Groups["numero"].Value);

                m = Regex.Match(ligne, ";(?<lettres>[A-Z]{2});");
                if (m.Success)
                    nouveau.Lettres = m.Groups["lettres"].Value;

                m = Regex.Match(ligne, @";(?<date>\d{2}-\d{2}-\d{4});");
                if (m.Success)
                    nouveau.Date = Convert.ToDateTime(m.Groups["date"].Value);

                m = Regex.Match(ligne, ";(?<commentaire>[A-Za-z ]+);");
                if (m.Success)
                    nouveau.Commentaire = m.Groups["commentaire"].Value;

            }


        }
    }
}


Pour que je puisse affiner, y'a t il des colonnes qui ne bougent pas (comme la première), par exemple si les commentaires sont toujours à la fin (même si le nombre de colonnes varie) ça serait une solution pour s'en sortir.
0
Whismeril Messages postés 19024 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 18 avril 2024 656
10 févr. 2017 à 13:09
Avec cette Regex, c'est mieux
(?<reference>\d{3});(?=(?:.*;)?(?<lettres>[A-Z]{2});)(?=(?:.*;)?(?<grandNombre>\d+);)(?=(?:.*;)?(?<date>\d{2}-\d{2}-\d{4});)(?=(?:.*;)?(?<commentaire>[A-Za-z ]{3,});)


Tester sur
une ligne d'entête qui sert à rien
380;111111111111111111;ET;02-02-2017;Desactive;
380;EC;2222222222222222;02-02-2017;liste noire;
380;3333333333333333;02-02-2017;AB;Desactive;
550;Desactive;02-02-2017;ET;4444444444444444;
550;5555555555555555;ET;02-02-2017;Desactive;


4 choses à respecter:
  • chaque ligne commence par un nombre à 3 chiffres
  • chaque ligne se termine par un ;
  • les autres colonnes ne sont pas vides
  • le commentaire ne contient que des lettres et des espaces



Tu peux tester ici
http://regexstorm.net/tester

ça donne


Y'a même pas besoin de lire le fichier ligne par ligne
0
Rejoignez-nous