Search code examples
csvhelper

Using CsvHelper to read a CSV with headers and refer to imported data by column name


I'm working on importing .CSV files which will be user configurable on columns and names.

On my side I will be processing / importing the data dynamically into a database but I need to match columns with their header name.

In addition, this is running as a service so I need async methods.

It looks like CsvDataReader (https://joshclose.github.io/CsvHelper/examples/data-table) may be somewhat what I'm looking for but I don't see an async method.

For example, I may have a CSV that looks like this:

id,first,last
101,john,doe
..

What I need to be able to do on the code side is this: (prototyped/"ideal")

foreach( var item in csvRead)
{
    column = csvRead.columnName;
    value = csvRead.value;
    DBWrite(column, value);
}

Is this possible to do with CsvHelper? (And most importantly, does the necessary classes exist for async?)


Solution

  • You can use a dynamic object.

    public async Task WriteRecords()
    {
        using (MemoryStream stream = new MemoryStream())
        using (StreamWriter writer = new StreamWriter(stream))
        using (StreamReader reader = new StreamReader(stream))
        using (CsvReader csv = new CsvReader(reader))
        {
            writer.WriteLine("id,first,last");
            writer.WriteLine("101,john,doe");
            writer.Flush();
            stream.Position = 0;
    
            await csv.ReadAsync();
    
            csv.ReadHeader();
    
            while (await csv.ReadAsync())
            {
                var record = csv.GetRecord<dynamic>();
    
                foreach (var item in (IDictionary<string, object>)record)
                {
                    DBWrite(item.Key, item.Value);
                }
            }
        }
    }
    
    public void DBWrite(string column, object value)
    {
        Console.WriteLine($"Storing {column}: {value}");
    }