Search code examples
csvhelper

CsvHelper create a ClassMap<ClassA> that contains a property as List Items to writes to csv file


Have some classes:

Class A
{ 
    public ClassC PropertyC {get;set; }
    public List<ClassB> PropertyBs { get;set; }
}
Class B { public ClassE PropertyE {get;set; } }

Class C { public ClassD PropertyD {get;set; } }

Have created :

A wrapper to make columns init later in some Infrastructure class, not right in ctor

public abstract class WrapMap<T>: ClassMap<T>
    {
        public virtual void Configure(List<CsvColumnDefinition> columns) { }
    }

public sealed class ClassAMap: WrapMap<ClassA>
{
      public override void Configure(List<CsvColumnDefinition> columns)
      {
          var column = columns.FirstOrDefault..... 
          Map(m => m.PropertyC.PropertyD).MapColumn(column);  // -- works fine ! MapColumn just do index and hide/show
          Map(m = m.PropertyBs) ???? what should be here Reference ? 
      }
}

Is it possible to create a map for the PropertyBs mapping without creating extra class? I've created a ClassBMap for PropertyBs and tried with Reference(m => m.PropertyBs) , but nothing seems helps.

I expected to see some result like:

ClassC, ClassB.ClassE, ClassB.ClassD
L     ,  N           ,  H
L     ,  G           ,  J
S     ,  Y           ,  T

Solution

  • This might be close to what you were looking for. I don't believe there is any way to do what you want through a single ClassMap

    public class Program
    {
        public static void Main(string[] args)
        {
            var records = new List<ClassA>
            {
                new ClassA {
                    PropertyC = new ClassC { Id = "L" },
                    PropertyBs = new List<ClassB> {
                        new ClassB {
                            PropertyD = "N",
                            PropertyE = "H" },
                        new ClassB {
                            PropertyD = "G",
                            PropertyE = "J"}
                        }
                    },
                new ClassA {
                    PropertyC = new ClassC { Id = "S" },
                    PropertyBs = new List<ClassB> {
                        new ClassB {
                            PropertyD = "Y",
                            PropertyE = "T" }
                    }
                }
            };
    
            using (var csv = new CsvWriter(Console.Out))
            {
                csv.Configuration.RegisterClassMap<ClassBMap>();
                csv.Configuration.RegisterClassMap<ClassCMap>();
    
                csv.WriteHeader<ClassC>();
                csv.WriteHeader<ClassB>();
                csv.NextRecord();
    
                foreach (var record in records)
                {
                    foreach (var item in record.PropertyBs)
                    {
                        csv.WriteRecord(record);
                        csv.WriteRecord(item);
                        csv.NextRecord();
                    }
                }
            }
    
            Console.ReadKey();
        }
    
    }
    
    public class ClassA
    {
        public ClassC PropertyC { get; set; }
        public List<ClassB> PropertyBs { get; set; }
    }
    
    public class ClassB {
        public string PropertyD { get; set; }
        public string PropertyE { get; set; }
    }
    
    public class ClassC {
        public string Id { get; set; }
    }
    
    public class ClassCMap : ClassMap<ClassC>
    {
        ClassCMap()
        {
            Map(m => m.Id).Name("ClassC");
        }
    }
    
    public class ClassBMap : ClassMap<ClassB>
    {
        ClassBMap()
        {
            Map(m => m.PropertyD).Name("ClassB.PropertyD");
            Map(m => m.PropertyE).Name("ClassB.PropertyE");
        }
    }