user6572294
user6572294

Reputation:

Write an object with a List<T> field to CSV

I'm learning C# and object serialization. I need to save an object in a .csv file. I tried CsvHelper but couldn't find the answer to my question.

Suppose I have an object like this:

public class Record
{
    ...
    public List<string> Collection { get; set; }
    ...
}

How do I use CsvHelper to store the values of Collection in a .csv file along with other primitive types in a record of csv file?

Upvotes: 0

Views: 2266

Answers (1)

David Specht
David Specht

Reputation: 9074

Collections are ignored by CsvHelper by default. However, using a ClassMap you can use Index to indicate you want a simple collection of string to be output with the other properties. (Not well documented.)

public class Program
{
    public static void Main(string[] args)
    {
        var records = new List<Record>
        {
            new Record { Id = 1, Name = "Record1", Collection = new List<string>{"First", "Second", "Third"}},
            new Record { Id = 2, Name = "Record2", Collection = new List<string>{"First", "Second"}},
        };

        using (var csv = new CsvWriter(Console.Out))
        {
            csv.Configuration.HasHeaderRecord = false;
            csv.Configuration.RegisterClassMap<RecordMap>();

            csv.WriteRecords(records);
        }

        Console.ReadKey();
    }

}

public class RecordMap : ClassMap<Record>
{
    public RecordMap()
    {
        Map(m => m.Id);
        Map(m => m.Name);
        Map(m => m.Collection).Index(3);
    }
}

public class Record
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<string> Collection { get; set; }
}

Outputs:

1,Record1,First,Second,Third
2,Record2,First,Second

If you know the max number of items in the Collection, you can also set an end index and have CsvHelper create the headings for each collection item.

public class RecordMap : ClassMap<Record>
{
    public RecordMap()
    {
        Map(m => m.Id);
        Map(m => m.Name);
        Map(m => m.Collection).Index(3, 5);
    }
}

Remove csv.Configuration.HasHeaderRecord = false; and now it will also print the header record for you. Outputs:

Id,Name,Collection1,Collection2,Collection3
1,Record1,First,Second,Third
2,Record2,First,Second

Upvotes: 2

Related Questions