Search code examples
c#csvcsvhelper

Why is my record map overwriting other fields in csvhelper?


I've defined a record map to change a list of strings into different columns, but for some reason the 'Result' fields are overwriting the other fields (Surname, DOB etc).

If I comment out the following line

Map(m => m.Result).Index(1,150);

then the output is otherwise correct, except no Result1, Result2, etc.

The number of results is variable for each record and maxes out at 150, which is why I've gone for this approach.

public class RecordMap : ClassMap<OutputRecord>
{
    public RecordMap()
    {
        Map(m => m.CustomerReference);
        Map(m => m.Forename);
        Map(m => m.Surname);
        Map(m => m.DOB);
        Map(m => m.Timestamp);
        Map(m => m.Score);
        Map(m => m.Result).Index(1,150);
    }
}

public class OutputRecord
{
    public string CustomerReference { get; set; }
    public string Forename { get; set; }
    public string Surname { get; set; }
    public string DOB { get; set; }        
    public DateTime Timestamp { get; set; }
    public string Score { get; set; }
    public List<string> Result { get; set; }
}

With the code as it is, the output is all mixed up, so the column headers don't correspond to the correct fields. The Result columns also start in position 3 of the output file, rather than being at the end as I would like.

Does anyone know why this is happening and how to avoid it? I want the Result list to be converted into one column per entry.

Thanks

Edit: adding code for the csv write as requested

using (var writer = new StreamWriter(OutputLocation.Text))
                using (var csv = new CsvWriter(writer))
                {
                    csv.Configuration.HasHeaderRecord = true;
                    csv.Configuration.RegisterClassMap<RecordMap>();

                    csv.WriteRecords(outputRecords);
                }

Solution

  • It is not actually overwriting Surname, DOB, etc. It is putting them at the end of the 150 Result records.

    The Index method takes two arguments. The first is the index where you want the field to start and the second is an optional end index for mapping IEnumerable members. If you want Result at the end of the other fields, you need to select a starting index that will put it after the other fields. The end index will also need to take into account where your start index started from.

    Map(m => m.Result).Index(6,155);