Search code examples
c#.netasp.net-web-apicsvhelper

CsvHelper try to export in csv a list which contain another list .net


I implement a web api in .Net Framework using csvHelper to export a csv.

I have the classes

public class StudentInfo
{
    public Student Student {get;set;}
    public Courses[] Courses { get; set; }
}

public class Student
{
    public string Id {get;set;}
    public string Name{ get; set; }
}

public class Course
{
   public string CourseId {get;set;}
   public string CourseName{ get; set; }
}

I have a method which return a List

public List<StudentInfo> FetchStudentInfo()
{
    //bla bla 
}

Now I want to export in a csv the List using the csvHelper

here is my code

List<StudentInfo> records = _service.FetchStudentInfo()
    using (StreamWriter sw = new StreamWriter(memoryStream))
    {
        using (var csv = new CsvWriter(sw))
        {        
            csv.WriteRecords(records);
            sw.Flush();
        }
    }

but this code export to csv only the object Students. How can export to csv for each student to have the list with the courses in the same line?

For example 12 jim java c# python

if i try

foreach(var item in records)
{
    csvWriter.WriteRecords(item.Student);//I have compile error because it want to pass an IEnumerable
    csvWriter.WriteRecords(item.Courses);
}

Solution

  • @dimmits answer works just fine and is easy to read. I thought I would provide another option that is more configuration based. It does require a modification to the StudentInfo class.

    public class Program
    {
        public static void Main(string[] args)
        {
            var studentInfos = FetchStudentInfo();
    
            using (var csv = new CsvWriter(Console.Out))
            {
                csv.Configuration.HasHeaderRecord = false;
                csv.Configuration.RegisterClassMap<StudentInfoMap>();
    
                csv.WriteRecords(studentInfos);
            }
    
            Console.ReadKey();
        }
    
        public static List<StudentInfo> FetchStudentInfo()
        {
            Course[] courses1 = { new Course { CourseId = "1", CourseName = "java" }, new Course { CourseId = "2", CourseName = "c#" }, new Course { CourseId = "3", CourseName = "python" } };
            Course[] courses2 = { new Course { CourseId = "1", CourseName = "java" }, new Course { CourseId = "2", CourseName = "c#" } };
            return new List<StudentInfo>
            {
                new StudentInfo{ Student = new Student{Id = "12", Name = "Jim"}, Courses = courses1 },
                new StudentInfo{ Student = new Student{Id = "45", Name = "Dave"}, Courses = courses2 }
            };
        }
    }
    
    public class StudentInfoMap : ClassMap<StudentInfo>
    {
        public StudentInfoMap()
        {
            References<StudentMap>(m => m.Student);
            Map(m => m.CourseNames).Index(3);
        }
    }
    
    public class StudentMap : ClassMap<Student>
    {
        public StudentMap()
        {
            Map(m => m.Id);
            Map(m => m.Name);
        }
    }
    
    public class StudentInfo
    {
        public Student Student { get; set; }
        public Course[] Courses { get; set; }
        public string[] CourseNames { get { return Courses.Select(c => c.CourseName).ToArray(); } }
    }
    
    public class Student
    {
        public string Id { get; set; }
        public string Name { get; set; }
    }
    
    public class Course
    {
        public string CourseId { get; set; }
        public string CourseName { get; set; }
    }