Чтение разных CSV с помощью CSVHelper

В основном то, что я пытаюсь сделать, - это прочитать файл CSV с помощью CSVHelper. Хитрость в том, что существует более одного файла (каждый раз, когда пользователь выбирает другой), и каждый из них имеет разную структуру.

Единственное, что они разделяют, - это сначала столбец с именем «Id», затем каждый из них имеет разное количество столбцов (от 2 дополнительных до 5) с разными типами данных.

Я пробовал сделать вот так:

public class Country
{
    public int Id { get; set; }
    public IList<string> Attributes { get; set; }
}

public sealed class CountryMap : CsvClassMap<Country>
{
    private List<string> attributeColumns = 
        new List<string> { "Attribute1", "Attribute2", "Attribute3", "Attribute4", "Attribute5" };

    public override void CreateMap()
    {
        Map(m => m.Id).Name("Id").Index(0);
        Map(m => m.Attributes).ConvertUsing(row =>
            attributeColumns
                .Select(column => row.GetField<string>(column))
                .Where(value => String.IsNullOrWhiteSpace(value) == false)
            );
    }
}

А затем с помощью:

using (var reader = new CsvReader(new StreamReader(FilePath,encoding.UTF8)))
{
    reader.Configuration.RegisterClassMap<CountryMap>();
    while (reader.Read())
    {
        var card = reader.GetRecord<Country>();
    }
}

Но я получаю только car = null.

Буду очень благодарен за любые советы и ответы.


person Jakub Karczewski    schedule 13.05.2016    source источник
comment
Используйте мой класс CSVReader на следующей веб-странице: stackoverflow.com/questions/30129406/. Результаты помещаются в DataTable. Вы можете вызвать класс более одного раза и поместить 2-й результат в другой DataTable. Использование соединения для объединения двух таблиц данных.   -  person jdweng    schedule 13.05.2016


Ответы (1)


Другой подход - просто использовать .Net OleDB, чтобы создать для вас DataTable из CSV-файла. Поскольку DataTable уже будет содержать необходимые данные схемы, он должен упростить сопоставление столбцов файла с вашими внутренними классами.

    using System.Data;
    using System.Data.OleDb;
    using System.IO;

    namespace App.Data
    {
        public class CsvFileHelper
        {
            public static DataTable ReadAsDataTable(string fileFullName)
            {
                DataTable tableCSV;

                using (OleDbConnection connection = new OleDbConnection("Provider=Microsoft.Jet.OleDb.4.0; Data Source = " + Path.GetDirectoryName(fileFullName) + "; Extended Properties = \"Text;HDR=YES;FMT=Delimited\""))
                {
                    connection.Open();

                    using (OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM " + Path.GetFileName(fileFullName), connection))
                    {
                        DataSet ds = new DataSet("CSVDataSet");
                        adapter.Fill(ds);

                        tableCSV = ds.Tables[0];
                    }
                }

                return tableCSV;
            }
        }
    }
person Edmond Quinton    schedule 13.05.2016
comment
Спасибо, это было буквально то, что я искал. Я не знал об этом, потому что только начал работать на C #. - person Jakub Karczewski; 14.05.2016