2016-07-15 2 views
-1

Supposons que j'ai un fichier csv contenant les éléments suivants:colonnes csv et les cartographier

Column1,Column2,Column3 
Supermario,1989,Nintendo 

Cependant, je veux staticly définir les en-têtes de colonne valides tels que:

Game_Name,Year,Console_Name 

Je voudrais permettre l'utilisateur de la carte les en-têtes dans le csv aux en-têtes valides statiques comme ceci:

Column1 ---- Game_Name 
Column2 ---- Year 
Column3 ----- Console_Name 

Je ne parviens pas à f imaginer comment je pourrais accomplir cette tâche. J'ai utilisé csvhelper avant de lire les fichiers CSV mais ici, je veux permettre à l'utilisateur de définir ses propres en-têtes de colonnes, et quand mon application de formulaire s'exécute je veux les mapper aux en-têtes de colonne valides.

Dans la section suivante dans l'extrait que Jeff a mentionné:

public MyDataClassMap() 
    { 
     Map(x => x.GameName).Name("Column1"); 
     Map(x => x.Year).Name("Column2"); 
     Map(x => x.ConsoleName).Name("Column3"); 
    } 

Ici, il ressemble à « Colonne1 » et le reste d'entre eux sont mappées manuellement pas dynamiquement ... Je ne sais pas ce que le colonnes va être nommé alors comment cela fonctionnerait-il? Si les colonnes étaient toujours nommées Colonne1, Colonne2, etc., cela fonctionnerait mais parfois sa Colonne1 parfois sa Col1 parfois sa C1 c'est arbitraire.

Quelle est une solution possible à cela?

Merci,

+0

pourquoi ne pas utiliser en-tête de colonne dans la première ligne plutôt que d'utiliser Column1, Colonne2, Colonne3? – Mark

+0

Je ne crée pas le fichier que quelqu'un d'autre crée le fichier csv et je n'en ai pas le contrôle Je voudrais que l'utilisateur final puisse le mapper lui-même – RobertC

Répondre

0

Utilisation CsvHelper, créer une carte de classe pour votre type de données, inscrivez-vous, lisez alors dans.

class MyData 
{ 
    public string GameName { get; set; } 
    public string Year { get; set; } 
    public string ConsoleName { get; set; } 
} 

class MyDataClassMap : CsvClassMap<MyData> 
{ 
    public MyDataClassMap() 
    { 
     Map(x => x.GameName).Name("Column1"); 
     Map(x => x.Year).Name("Column2"); 
     Map(x => x.ConsoleName).Name("Column3"); 
    } 
} 
public List<MyData> ReadMyData(string path) 
{ 
    using (var file = File.OpenText(path)) 
    using (var reader = new CsvReader(file)) 
    { 
     reader.Configuration.RegisterClassMap<MyDataClassMap>(); 
     return reader.GetRecords<MyData>().ToList(); 
    } 
} 

Si vous connaissez les noms des en-têtes peut changer mais pas l'ordre des colonnes, vous pouvez les mapper par index à la place.

public MyDataClassMap() 
{ 
    Map(x => x.GameName).Index(0); 
    Map(x => x.Year).Index(1); 
    Map(x => x.ConsoleName).Index(2); 
} 

Sinon, vous pouvez ajouter des paramètres à votre constructeur afin que vous pouvez fournir les noms des colonnes, puis instancier votre carte.

public MyDataClassMap(string gameNameCol, string yearCol, string consoleNameCol) 
{ 
    Map(x => x.GameName).Name(gameNameCol); 
    Map(x => x.Year).Name(yearCol); 
    Map(x => x.ConsoleName).Name(consoleNameCol); 
} 
public List<MyData> ReadMyData(string path, 
     string gameNameCol, string yearCol, string consoleNameCol) 
{ 
    using (var file = File.OpenText(path)) 
    using (var reader = new CsvReader(file)) 
    { 
     reader.Configuration.RegisterClassMap(
      new MyDataClassMap(gameNameCol, yearCol, consoleNameCol)); 
     return reader.GetRecords<MyData>().ToList(); 
    } 
} 
+0

hypothétiquement si j'ai créé une autre entrée dans MyDataClassMap() appelée M (x => x.Publisher) .Name ("Column4"); Serais-je jeter une exception si cette colonne n'était pas dans mon fichier csv? comment pourrais-je y remédier? ou existe-t-il une solution de contournement pour un tel scénario? – RobertC

+0

En mappant une colonne à une propriété, vous indiquez que la colonne correspondante doit exister. S'il y a une possibilité que ce ne soit pas le cas, vous devrez fournir votre propre convertisseur et vérifier si vous pouvez lire cette colonne manquante et fournir une valeur par défaut appropriée si ce n'est pas le cas. –

+0

Salut Jeff, c'est génial je pense que ce serait certainement la réponse que je recherche, sauf pour le petit détail qui de l'extrait ci-dessus il ne semble pas dynamique, il semble que je suis encore la cartographie Colonne1, Colonne2 etc. Statiquement je ne vois pas comment je passerais les en-tetes variables qui me permettraient de le faire dynamiquement. – RobertC