C# CsvHelper尝试以csv格式导出包含另一个列表的列表.net

C# CsvHelper尝试以csv格式导出包含另一个列表的列表.net,c#,.net,asp.net-web-api,csvhelper,C#,.net,Asp.net Web Api,Csvhelper,我在.Net Framework中实现了一个web api,使用csvHelper导出csv 我有课 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;

我在.Net Framework中实现了一个web api,使用csvHelper导出csv

我有课

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; }
}
我有一个返回列表的方法

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

CSV格式不能表示列表中的列表。我不知道在导出后读取CSV时如何解释数据

要将复杂数据导出到平面文件中,必须首选XML或JSON

如果您确实希望以CSV文件的形式获取,则必须使用两个不同的分隔符来区分这两个类(例如:对于StudentInfo使用“,”对于课程使用“;”

之后,我将为表示CSV数据创建一个类:

public class StudentInfoCsv
{
    public Student Student {get;set;}
    public string Courses { get; set; }
}

List<StudentInfoCsv> csvData = new List<StudentInfoCsv>
foreach(var item in records)
{
    StudentInfoCsv.Add(new StudentInfoCsv()
    {
        Student = item.Student,
        Courses = CsvSerializer.SerializeToCsv(item.Courses)
    }
}
csvWriter.WriteRecords(csvData);
公共课堂学生信息
{
公立学生学生{get;set;}
公共字符串{get;set;}
}
列表csvData=新列表
foreach(记录中的var项目)
{
添加(新的StudentInfoCsv()
{
学生=项目。学生,
Courses=CsvSerializer.SerializeToCsv(item.Courses)
}
}
csvWriter.WriterRecords(csvData);
解决方案是

                       foreach (StudentInfo item in records)
                        {
                            csvWriter.WriteField(item.Student.Id);
                            csvWriter.WriteField(item.Student.Name);

                            foreach (var row in item.Courses)
                            {
                                csvWriter.WriteField(row.CourseName);
                            }
                            csvWriter.NextRecord();
                        }
输出将是

12 jim java c#python


@Dimmit的答案很好用,也很容易阅读。我想我会提供另一个更基于配置的选项。它确实需要修改
StudentInfo

公共类程序
{
公共静态void Main(字符串[]args)
{
var studentinfo=FetchStudentInfo();
使用(var csv=new CsvWriter(Console.Out))
{
csv.Configuration.HasHeaderRecord=false;
csv.Configuration.RegisterClassMap();
csv.书面记录(学生信息);
}
Console.ReadKey();
}
公共静态列表FetchStudentInfo()
{
课程[]课程1={新课程{CourseId=“1”,CourseName=“java”},新课程{CourseId=“2”,CourseName=“c#”},新课程{CourseId=“3”,CourseName=“python”};
课程[]课程2={新课程{CourseId=“1”,CourseName=“java”},新课程{CourseId=“2”,CourseName=“c#”};
返回新列表
{
新学生信息{Student=newstudent{Id=“12”,Name=“Jim”},Courses=courses1},
新学生信息{Student=newstudent{Id=“45”,Name=“Dave”},Courses=courses2}
};
}
}
公共班级学生信息地图:班级地图
{
公共学生信息地图()
{
参考文献(m=>m.Student);
Map(m=>m.CourseNames)指数(3);
}
}
公共班级学生地图:班级地图
{
公共学生地图()
{
Map(m=>m.Id);
Map(m=>m.Name);
}
}
公共班级学生信息
{
公立学生学生{get;set;}
公共课程[]课程{get;set;}
公共字符串[]CourseName{get{return Courses.Select(c=>c.CourseName.ToArray();}
}
公立班学生
{
公共字符串Id{get;set;}
公共字符串名称{get;set;}
}
公共课
{
公共字符串CourseId{get;set;}
公共字符串CourseName{get;set;}
}

CSV文件存储数据行,每列用逗号分隔符分隔。因此,它们只能表示一种实体类型。如果要嵌套类型(学生中的课程),则需要序列化为不同的格式。最明显的选择是JSON(Newtonsoft.JSON或System.Text.JSON)。我建议使用JSON或XML进行序列化,因为两者都允许比CSV更复杂的结构。非常感谢David,我接受您的意见作为解决方案。这是一种非常好的方法!
public class StudentInfoCsv
{
    public Student Student {get;set;}
    public string Courses { get; set; }
}

List<StudentInfoCsv> csvData = new List<StudentInfoCsv>
foreach(var item in records)
{
    StudentInfoCsv.Add(new StudentInfoCsv()
    {
        Student = item.Student,
        Courses = CsvSerializer.SerializeToCsv(item.Courses)
    }
}
csvWriter.WriteRecords(csvData);
                       foreach (StudentInfo item in records)
                        {
                            csvWriter.WriteField(item.Student.Id);
                            csvWriter.WriteField(item.Student.Name);

                            foreach (var row in item.Courses)
                            {
                                csvWriter.WriteField(row.CourseName);
                            }
                            csvWriter.NextRecord();
                        }