csvhelper - как создать маппер для сложного объекта

Я пытаюсь написать сложный объект (содержит списки) как плоский объект.

public class PersonDTO
{
    public Guid Id { get; set; }
    public PersonDetails details { get; set; }
    public List<Book> Books { get; set; }
}

public class PersonDetails
{
    public string FName { get; set; }
    public string LName { get; set; }
}

public class Book
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public List<Page> Pages { get; set; }
}

public class Page
{
    public Guid Id { get; set; }
}

Количество записей csv должно соответствовать длине внутренней коллекции.

Например, у PersonDTO есть список книг, у книги есть список страниц. Я хотел бы получить следующий csv:

personId | FName | LName | BookId | BookName | PageId

   1     | name1 | name1 |    1   |   book1  |   1
   1     | name1 | name1 |    1   |   book1  |   2
   1     | name1 | name1 |    1   |   book1  |   3
   1     | name1 | name1 |    2   |   book2  |   1
   1     | name1 | name1 |    2   |   book2  |   2
   2     | name2 | name2 |    3   |   book3  |   1
   2     | name2 | name2 |    3   |   book3  |   2
   2     | name2 | name2 |    3   |   book3  |   3

Я нашел несколько способов реализовать это (используя Linq/создать новый плоский объект). Есть ли способ реализовать это только с картами классов CsvHealper?


person Mhadipor    schedule 26.08.2019    source источник


Ответы (1)


Кажется, это работает.

public static void Main(string[] args)
{
    var records = GetRecords();
    using (var csv = new CsvWriter(Console.Out))
    {
        csv.Configuration.RegisterClassMap<PersonMap>();
        csv.Configuration.RegisterClassMap<BookMap>();
        csv.Configuration.RegisterClassMap<PageMap>();

        csv.WriteHeader<PersonDTO>();
        csv.WriteHeader<Book>();
        csv.WriteHeader<Page>();
        csv.NextRecord();

        foreach (var person in records)
        {
            foreach (var book in person.Books)
            {
                foreach (var page in book.Pages)
                {
                    csv.WriteRecord(person);
                    csv.WriteRecord(book);
                    csv.WriteRecord(page);
                    csv.NextRecord();
                }
            }
        }
    }

    Console.ReadKey();
}

public sealed class PersonMap : ClassMap<PersonDTO>
{
    public PersonMap()
    {
        Map(m => m.Id).Name("PersonId");
        References<PersonDetailsMap>(m => m.details);
    }
}

public sealed class PersonDetailsMap : ClassMap<PersonDetails>
{
    public PersonDetailsMap()
    {
        Map(m => m.FName);
        Map(m => m.LName);
    }
}

public sealed class BookMap : ClassMap<Book>
{
    public BookMap()
    {
        Map(m => m.Id).Name("BookId");
        Map(m => m.Name).Name("BookName");
    }
}

public sealed class PageMap : ClassMap<Page>
{
    public PageMap()
    {
        Map(m => m.Id).Name("PageId");
    }
}
person David Specht    schedule 26.08.2019