我想将CSV反序列化为对象,按不同的列名进行映射,如以下示例所示:
输入1
ID,名称;文件
1;马修斯; 555777
2;克拉丽斯; 567890
输入2
“Id_Person”; “将First_Name”, “手机”
3; “约翰”; “999-9999”
public class People
{
public int PersonId { get; set; }
public string Name { get; set; }
public string Doc { get; set; }
}
请注意,列名称会按文件更改,甚至可能会丢失列。
我想将“Id”和“Id_Person”映射到PersonId属性,依此类推。
怎么做?
答案 0 :(得分:0)
实际上找到了解决我问题的方法:CsvHelper
设置:
public sealed class PessoaCSVMap : ClassMap<Pessoas>
{
public PessoaCSVMap()
{
Map(m => m.NomeCompleto).Name("Nome", "Name");
Map(m => m.Documento).Name("Documento", "Doc", "CPF");
Map(m => m.Email1).Name("Email", "Email1", "E-mail", "E-mail1");
Map(m => m.PessoaId).Ignore();
}
}
使用:
const string CSV = "Nome;Email;bleu\nMatheus;matheus.lacerda@email.com.br;blau\nClarice;null;null";
CsvReader csv = new CsvReader(new StringReader(CSV));
csv.Configuration.RegisterClassMap<PessoaCSVMap>();
csv.Configuration.Delimiter = ";";
csv.Configuration.HeaderValidated = null;
csv.Configuration.MissingFieldFound = null;
List<Pessoas> pessoas = csv.GetRecords<Pessoas>().ToList();
答案 1 :(得分:0)
假设您已经可以阅读特定的CSV行,那么这个可以通过一些反射和泛型来提供很大的灵活性。不适用于所有方法,但它可以很容易地适应不同的情况:
public IEnumerable<T> ProccessCSV<T>(StreamReader document, char divider)
where T : class, new()
{
string currentLine = reader.ReadLine();
string[] usedHeaders = currentLine.Split(divider);
while ((currentLine = reader.ReadLine()) != null)
{
var fields = currentLine.Split(divider);
var result = new T();
for (var i = 0; i < usedHeaders.Length; i++)
{
var value = fields[i];
var propInfo = typeof(T).GetProperties()[i];
result.GetType()
.GetProperty(propInfo.Name)
.SetValue(result, value);
}
yield return result;
}
}
希望这可以作为可能解决方案的支柱。
对于第一种情况,您需要使用分隔符&#39;;&#39;还有一个类:
public class Person
{
public string Id { get; set; }
public string Name { get; set; }
public string Document { get; set; }
}