我的查询结果数据是学生数据的集合。每个学生集合都有一个相关的联系人集合。
有些学生没有联系,有些学生有几个。
我需要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。如有必要,我可以更新。
答案 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
希望它有所帮助。