2016-07-15 52 views
-1

假设我有一个包含以下csv文件:CSV栏并将其映射

Column1,Column2,Column3 
Supermario,1989,Nintendo 

但是我想staticly定义有效的列标题如:

Game_Name,Year,Console_Name 

我想允许用户将csv中的标题映射到静态有效标题,如下所示:

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

我遇到问题了f确定如何完成这项任务。

我以前用csvhelper来读csv文件,但在这里我想允许用户定义自己的列标题,并且当我的表单应用程序运行时,我想将它们映射到有效的列标题。

在片段中的以下部分,杰夫提到:

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

这看起来像“列1”和他们其余的人都被映射手动不会动态...我不知道是什么列将被命名,那么这将如何工作?如果这些列总是被命名为Column1,Column2等等,这可以工作,但有时它的Column1有时候它的Col1有时它的C1它是任意的。

什么是可能的解决方案呢?

感谢,

+0

为什么不第一行中使用列标题,而不是使用列1,列2,栏3? – Mark

+0

我不创建文件别人正在创建csv文件,我没有它的控制我想最终用户能够映射它自己 – RobertC

回答

0

使用CsvHelper,创建一个类的地图为您的数据类型,注册,然后在读它。

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(); 
    } 
} 

如果您知道标题名称可能会改变,但列顺序不会,你可以通过索引来映射它们。

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

否则,你可以将参数添加到您的构造函数,以便您可以提供的列名,然后实例化地图。

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

假设如果我在MyDataClassMap()中创建另一个条目称为M( x => x.Publisher).Name(“Column4”);如果该列不在我的csv文件中,该ID会引发异常?我该如何补救?或者是否有解决此类情况的方法 – RobertC

+0

通过将列映射到属性,您指出相应的列必须存在。如果有可能没有,您必须提供自己的转换器,并检查是否可以从缺失的列中读取数据,并提供适当的默认值(如果不存在)。 –

+0

嗨,杰夫,这是伟大的我认为这肯定会是我正在寻找的答案,除了从上面的代码片段看起来不动态的小细节,它看起来像我仍然映射Column1,Column2等等。静态地我看不到我会怎样传递可以动态实现的变量头。 – RobertC