Search code examples
c#csvcsvhelper

How to solve problem with CSV Mapping using CsvHelper


I have a CSV File with multiple fields(check below for format)

ArticleNumber;Shop1;Shop2;Shop3;Shop4;Shop5;Shop6;Shop7
123455;50;51;52;53;54;55;56

In fields Shop1,Shop2....Shop7 I have product Prices. I receive file like this, so I need to find a cool way to solve my problem. I want to read this CSV using CsvHelper library, but I don't know how to map fields. As a result I want something like this:

ArticleNumber Shop Price
123455 Shop1 50
123455 Shop2 51
123455 Shop3 52
123455 Shop4 53
123455 Shop5 54
123455 Shop6 55

Solution

  • I think this will get you the format you are looking for.

    void Main()
    {
        var config = new CsvConfiguration(CultureInfo.InvariantCulture)
        {
            Delimiter = ";"
        };
        
        using (var reader = new StringReader("ArticleNumber;Shop1;Shop2;Shop3;Shop4;Shop5;Shop6;Shop7\n123455;50;51;52;53;54;55;56\n123456;60;61;62;63;64;65;66"))
        using (var csv = new CsvReader(reader, config))
        {
            csv.Context.RegisterClassMap<ArticleMap>();
            
            csv.Read();
            csv.ReadHeader();
            
            var shops = csv.HeaderRecord.Skip(1).ToArray();
            
            var records = csv.GetRecords<Article>().ToList();
    
            var results = records.SelectMany(r => r.Shop
                                    .Select((s, i) => new ArticleShop 
                                                        { 
                                                            ArticleNumber = r.ArticleNumber, 
                                                            Shop = shops[i], 
                                                            Price = s
                                                        })
                                    ).ToList();
        }   
    }
    
    public class ArticleMap : ClassMap<Article>
    {
        public ArticleMap()
        {
            Map(x => x.ArticleNumber);
            Map(x => x.Shop).Index(1);
        }
    }
    
    public class Article
    {
        public int ArticleNumber { get; set; }
        public List<double> Shop { get; set; }
    }
    
    public class ArticleShop
    {
        public int ArticleNumber { get; set; }
        public string Shop { get; set; }
        public double Price { get; set; }
    }