Assume I have a large csv file that I'd like to read, modify and write back. Perhaps I want to change a field separator from comma to tab. Perhaps I want to change the quotation character from ' to ". Or may be I want to add a plus sign to each value in the first column. Since the file is large, I do not want to load it in memory all at once, I'd like to read it record by record.
So I write a code like this:
var inPath = @"infile.txt";
var outPath = @"outfile.txt";
CsvConfiguration readCf = GetReadConfiguration();
CsvConfiguration writeCf = GetWriteConfiguration();
using (var streamin = new FileStream(inPath, FileMode.Open))
using (var streamReader = new StreamReader(streamin))
{
using (var csvReader = new CsvReader(streamReader, readCf))
using (var csvWriter = new CsvWriter(new StreamWriter(outPath), writeCf))
{
while (csvReader.Read())
{
var currentRecord = csvReader.GetRecord<dynamic>();
UpdateRecord(currentRecord);
csvWriter.WriteRecord(currentRecord);
}
}
}
This fails at run time with the following error:
Types that inherit IEnumerable cannot be auto mapped. Did you accidentally call GetRecord or WriteRecord which acts on a single record instead of calling GetRecords or WriteRecords which acts on a list of records?
Note, that nothing interesting happens in UpdateRecord
, in fact this line above can be completely commented out.
What happens is that GetRecord
returns an ExpandoObject
and then WriteRecord
chokes on this object.
What is the best way to make this work?
Update
Just so it's clear: I fully realize that I'm getting this error is because CSVHelper does not support ExpandoObject
s for WriteRecord
call. I'm looking for suggestions, for easiest way to make this work.
It appears that ability to write ExpandoObject
is added in this commit.
Note that this is not in the latest nuget release (2.16.3 as of the time of writing) but for the next 3.x release. If it's an option for you get latest beta from github and use that.
If you do, note that you will have to call NextRecord
after each WriteRecord
. In 2.16.3 CVSHelper would call it for you, so it's a bit of a breaking API change
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With