I am using C# console application to read a .CSV
file, process it and save the data into a database. While reading the code, I get the correct number of records, but all records are of the last record.
So for example, the file has 50 records and first column of last row is Shane, the record in the below code will have 50 rows but each with the data from Shane row.
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
csv.Configuration.TrimOptions = CsvHelper.Configuration.TrimOptions.Trim;
var obj = new Students();
var records = csv.EnumerateRecords(obj); //Reads correct number of records but its only the last record multiple times.
}
What am I missing?
The problem, as others have commented, is that if you do something to enumerate your records, like calling records.ToList()
, your list is now full of references to the same obj, var obj = new Students();
.
csv.GetRecords<Student>().ToList()
is like having a notebook and writing out each record on each page. And your list looks like:[0] see page1
[1] see page2
[2] see page3
csv.EnumerateRecords(obj).ToList()
is like having a single sheet of paper and you use erasable ink or pencil for the actual data. As CsvReader
gives you the records, it takes less time to write them out because you don't have to write out FirstName: Foo
, LastName: Bar
, you can just erase the Foo
and the Bar
and write in the new data. But now your list looks like:[0] see page1
[1] see page1
[2] see page1
And your var obj
has now been overwritten with the last record that was yielded by CsvReader
.
If you wanted to save each individual record using EnumerateRecord
, you would need to save them as they were being enumerated.
var records = csv.EnumerateRecords(obj);
foreach (var record in records)
{
// Save record to database here.
}
Here is another way to see that you are looking at a list of the same object.
void Main()
{
var record1 = new Foo{ Id = 1, Name = "Fred"};
var record2 = new Foo{ Id = 1, Name = "Fred"};
var record3 = record1;
Console.WriteLine("record1 == record2: " + (record1 == record2));
Console.WriteLine("record1 == record3: " + (record1 == record3));
using (var reader = new StringReader("Id,Name\n1,Fred\n1,Fred"))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
var records = csv.GetRecords<Foo>().ToList();
Console.WriteLine("records[0] == records[1]: " + (records[0] == records[1]) + " (GetRecords)");
}
using (var reader = new StringReader("Id,Name\n1,Fred\n1,Fred"))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
var record = new Foo();
var records = csv.EnumerateRecords(record).ToList();
Console.WriteLine("records[0] == records[1]: " + (records[0] == records[1]) + " (EnumerateRecords)");
}
}
// You can define other methods, fields, classes and namespaces here
public class Foo
{
public int Id { get; set; }
public string Name { get; set; }
}
Outputs
record1 == record2: False
record1 == record3: True
records[0] == records[1]: False (GetRecords)
records[0] == records[1]: True (EnumerateRecords)