集合到csv的集合,每个嵌套集合的新行

时间:2018-05-06 15:48:39

标签: c# ienumerable csvhelper

我的查询结果数据是学生数据的集合。每个学生集合都有一个相关的联系人集合。

有些学生没有联系,有些学生有几个。

我需要2个csv来自这个学生系列。一个只是学生,一个我遇到麻烦的人:每个学生都有一排csv 和他们相关的联系。如果鲍比没有联系,那么他有一排。如果Suezy有3个联系人,那么她的3行信息 包含在行中的联系人数据。

我尝试使用CsvHelper来做这件事,但我没有按照我的预期结果。请参阅Josh Close的回答here

我使用csv' s作为我的样本数据,一名学生有2个联系人,2名学生每人有一个联系人。和1名没有联系的学生。

生:

StudentSisId    Name
111111          Betty
222222          Veronica
333333          Jughead
444444          Archie

联系人:

StudentSisId    Relationship
111111          Mother
111111          Father
222222          Mother
444444          Father

我的代码: 类:

public class Student
{
    public string StudentSisId { get; set; }
    public string Name { get; set; }
    public List<Contact> Contacts { get; set; }

}

public class Contact
{
    public string StudentSisId { get; set; }
    public string Relationship { get; set; }
}

映射:

    public sealed class StudentClassMap : ClassMap<Student>
    {
        public StudentClassMap()
        {
            Map(m => m.StudentSisId);
            Map(m => m.Name);
            Map(m => m.Contacts).Index(2);
        }
    }

    public sealed class ContactClassMap : ClassMap<Contact>
    {
        public ContactClassMap()
        {
            Map(m => m.StudentSisId).Index(1);
            Map(m => m.Relationship).Index(2);
        }
    }

代码:

    private static void StudentsWithContacts()
    {
        var csvReader = new ReadCsvFile();

        List<Student> students = csvReader.GetDataCollection<Student>(@"c:\temp\studentsWithoutContacts.csv");
        List<Contact> contacts = csvReader.GetDataCollection<Contact>(@"c:\temp\contacts.csv");

        foreach (var student in students)
        {
            if (contacts.Any(x => x.StudentSisId == student.StudentSisId))
            {
                var studentContacts = contacts.Where(x => x.StudentSisId == student.StudentSisId).ToList();
                student.Contacts = new List<Contact>();
                student.Contacts.AddRange(studentContacts);
            }
        }

        using (var textWriter = File.CreateText(@"c:\temp\studentsWithContacts.csv"))
        using (var writer = new CsvWriter(textWriter))
        {
            writer.WriteHeader<Student>();
            writer.WriteRecords(students);
        }
     }

这给出了结果(为什么Betty在标题中?):

StudentSisId姓名111111 Betty 222222 Veronica
333333 Jughead
444444阿奇

我期待:

StudentSisId        Name        Relationship
111111              Betty       Mother
111111              Betty       Father
222222              Veronica    Mother
333333              Jughead 
444444              Archie      Father

我是在正确的轨道上,还是我误解了这个工具?此示例为CsvHelper 3.2。如有必要,我可以更新。

1 个答案:

答案 0 :(得分:1)

我不太熟悉csvhelper来处理你的需求。但是使用Cinchoo ETL / Linq,您可以执行文件合并,如下所示。

string csv1 = @"StudentSisId,Name
111111,Betty
222222,Veronica
333333,Jughead
444444,Archie";

string csv2 = @"StudentSisId,Relationship
111111,Mother
111111,Father
222222,Mother
444444,Father
";

StringBuilder sb = new StringBuilder();
using (var p1 = ChoCSVReader.LoadText(csv1)
    .WithFirstLineHeader()
    )
{
    using (var p2 = ChoCSVReader.LoadText(csv2)
        .WithFirstLineHeader()
        )
    {
        var j1 = from r1 in p1
                    join r2 in p2
                    on r1.StudentSisId equals r2.StudentSisId into p22
                    from r22 in p22.DefaultIfEmpty()
                select new { StudentSisId = r1.StudentSisId, Name = r1.Name, Relationship = r22 != null ? r22.Relationship : null };

        using (var w = new ChoCSVWriter(sb)
            .WithFirstLineHeader()
            )
            w.Write(j1);
    }
}

Console.WriteLine(sb.ToString());

<强>输出:

StudentSisId,Name,Relationship
111111,Betty,Mother
111111,Betty,Father
222222,Veronica,Mother
333333,Jughead,
444444,Archie,Father

希望它有所帮助。