是否有用于将CSV随机列顺序映射到已定义属性的代码模式?

我有一个CSV,从各种来源提供给我的应用程序。 CSV将始终具有相同的数字列,并且列的标题值将始终相同。

但是,列可能并不总是按相同的顺序排列。

第1天CSV可能如下所示

ID,FirstName,LastName,Email 1,Johh,Lennon,jlennon@applerecords.com 2,Paul,McCartney,macca@applerecords.com 

第2天CSV可能如下所示

 Email,FirstName,ID,LastName resident1@friarpark.com,George,3,Harrison ringo@allstarrband.com,Ringo,4,Starr 

我想读取每个文件的标题行,并有一个简单的机制,用于将每个“列”数据与我在类中定义的相关属性相关联。

我知道我可以使用选择语句来解决它,但这似乎是一种处理它的“坏”方式。

有没有一种简单的方法可以在运行时使用字典或类将“列”映射到属性?

使用“词典”将列标题文本映射到列位置。 列标题文本到对象属性的硬代码映射。

例:

 // Parse first line of text to add column heading strings and positions to your dictionary ... // Parse data row into an array, indexed by column position ... // Assign data to object properties x.ID = row[myDictionary["ID"]]; x.FirstName = row[myDictionary["FirstName"]]; ... 

你不需要为此目的设计模式。

http://www.codeproject.com/Articles/9258/A-Fast-CSV-Reader

我使用过这个阅读器,虽然非常好,它有一个row["firstname"]row["id"] ,你可以解析它并创建你的对象。

我使用Microsoft.VisualBasic.FileIO.TextFieldParser解析了两个CSV文件。 我解析了两个csv文件后填充了DataTable

 DataTable dt; private void button1_Click(object sender, EventArgs e) { dt = new DataTable(); ParseCSVFile("day1.csv"); ParseCSVFile("day2.csv"); dataGridView1.DataSource = dt; } private void ParseCSVFile(string sFileName) { var dIndex = new Dictionary(); using (TextFieldParser csvReader = new TextFieldParser(sFileName)) { csvReader.Delimiters = new string[] { "," }; var colFields = csvReader.ReadFields(); for (int i = 0; i < colFields.Length; i++) { string sColField = colFields[i]; if (sColField != string.Empty) { dIndex.Add(sColField, i); if (!dt.Columns.Contains(sColField)) dt.Columns.Add(sColField); } } while (!csvReader.EndOfData) { string[] fieldData = csvReader.ReadFields(); if (fieldData.Length > 0) { DataRow dr = dt.NewRow(); foreach (var kvp in dIndex) { int iVal = kvp.Value; if (iVal < fieldData.Length) dr[kvp.Key] = fieldData[iVal]; } dt.Rows.Add(dr); } } } } 

问题中提到的day1.csvday2.csv

以下是输出dataGridView1外观:

在此处输入图像描述

这是一个简单的通用方法,它将获取一个CSV文件(分解为string [])并从中创建一个对象列表。 假设对象属性与标题具有相同的名称。 如果不是这种情况,您可以查看DataMemberAttribute属性并相应地进行修改。

 private static List ProcessCSVFile(string[] lines) { List list = new List(); Type type = typeof(T); string[] headerArray = lines[0].Split(new char[] { ',' }); PropertyInfo[] properties = new PropertyInfo[headerArray.Length]; for (int prop = 0; prop < properties.Length; prop++) { properties[prop] = type.GetProperty(headerArray[prop]); } for (int count = 1; count < lines.Length; count++) { string[] valueArray = lines[count].Split(new char[] { ',' }); T t = Activator.CreateInstance(); list.Add(t); for (int value = 0; value < valueArray.Length; value++) { properties[value].SetValue(t, valueArray[value], null); } } return list; } 

现在,为了使用它,只需将您的文件格式化为字符串数组。 假设您想要阅读的课程如下所示:

 class Music { public string ID { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Email { get; set; } } 

所以你可以这样称呼:

 List newlist = ProcessCSVFile(list.ToArray()); 

......一切都通过一个电话完成。