有没有办法将CSV反序列化为对象,按不同的列名进行映射?

时间:2018-01-17 12:35:04

标签: c# csv asp.net-core-2.0

我想将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属性,依此类推。

怎么做?

2 个答案:

答案 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; }
}

基于:https://www.pluralsight.com/guides/microsoft-net/building-a-generic-csv-writer-reader-using-reflection