Search code examples
csv.net-coremappingcsvhelper

How can I retrieve data from multiple objects from a .csv file using CsvHelper?


I have a list with type MyClass, and MyClass has several attributes. How can i retrieve data using CsvHelper, if .csv file looks like this? (Yes, attributes of type Data1 are numbered.)

Date       |   Data1  | Unit  |   Data2  | Unit  |   Data3  | Unit  | ... | DataN    |   Unit 
-----------|----------|-------|----------|-------|----------|-------|-----|----------|----------
2020.01.02 |     1    |   kW  |     3    |  kW   |    1.5   |  kW   | ... |     0    |    kW
2020.01.03 |     0    |   kW  |     4    |  kW   |     1    |  kW   | ... |     3    |    kW
2020.01.04 |     4    |   kW  |     2    |  kW   |     1    |  kW   | ... |     2    |    kW

This is what i want to see. The objects are stored in a list that can store MyClass type.


    List(MyClass) = [Object-1, Object-1, Object-3, ..., Object-N]

Object-1: [(2020.01.02.,1, kW),(2020.01.03.,0, kW),,(2020.01.04.,4, kW)]
Object-2: [(2020.01.02.,3, kW),(2020.01.03.,4, kW),,(2020.01.04.,2, kW)]
Object-3: [(2020.01.02.,1.5, kW),(2020.01.03.,1, kW),,(2020.01.04.,1, kW)]
...
Object-N: [(2020.01.02.,0, kW),(2020.01.03.,3, kW),,(2020.01.04.,2, kW)]



    MappedClass{
        private DateTime Date;
        private List List;
    }



    MyClass{
        private DateTime Date;
        private string A1; //Attribute1
        private int A2; //Attribute2
    }

If the properties of only one object are listed, then i can do the task, but not with multiple objects and this layout. I thought of reading the file row by row and then somehow pairing its related data.

How to do this task effectively?


Solution

  • This would be one way to do it.

    public class Program
    {
        public static void Main(string[] args)
        {
            using (MemoryStream stream = new MemoryStream())
            using (StreamWriter writer = new StreamWriter(stream))
            using (StreamReader reader = new StreamReader(stream))
            using (CsvReader csv = new CsvReader(reader, CultureInfo.InvariantCulture))
            {
                writer.WriteLine("Date,Data1,Unit,Data2,Unit,Data3,Unit");
                writer.WriteLine("2020.01.02,1,kw,3,kw,1.5,kw");
                writer.WriteLine("2020.01.03,0,kw,4,kw,1,kw");
                writer.Flush();
                stream.Position = 0;
    
                var records = new List<MappedClass>();
    
                csv.Read();
                csv.ReadHeader();
    
                while (csv.Read())
                {
                    var record = new MappedClass
                    {
                        Date = record.Date,
                        Date = csv.GetField<DateTime>(0),
                        List = new List<MyClass>()
                    };
    
                    for (int i = 1; i < csv.Context.HeaderRecord.Length; i += 2)
                    {
                        var item = new MyClass
                        {
                            Data = csv.GetField<decimal>(i),
                            Unit = csv.GetField<string>(i + 1)
                        };
    
                        record.List.Add(item);
                    }
    
                    records.Add(record);
                }
            }
        }
    }
    
    public class MappedClass
    {
        public DateTime Date { get; set; }
        public List<MyClass> List { get; set; }
    }
    
    public class MyClass {
        public DateTime Date;
        public string Unit; //Attribute1
        public decimal Data; //Attribute2
    }