如何使用 CsvHelper 解决 CSV 映射问题

Posted

技术标签:

【中文标题】如何使用 CsvHelper 解决 CSV 映射问题【英文标题】:How to solve problem with CSV Mapping using CsvHelper 【发布时间】:2022-01-01 00:58:23 【问题描述】:

我有一个包含多个字段的 CSV 文件(请查看下面的格式)

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

在字段 Shop1,Shop2....Shop7 我有产品价格。我收到这样的文件,所以我需要找到一种很酷的方法来解决我的问题。 我想使用 CsvHelper 库读取这个 CSV,但我不知道如何映射字段。结果我想要这样的东西:

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

【问题讨论】:

【参考方案1】:

我认为这将为您提供所需的格式。

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; 

【讨论】:

David Specht,这就像一个魅力。非常感谢你的帮助。我很欣赏它。 很高兴它对您有用!如果这解决了您的问题,如果您将答案标记为已接受,将对其他人有所帮助。【参考方案2】:

您的 CSV 文件的格式是否已设置,或者可以更改吗? 如果可以更改,您可以将其更改为

ArticleNumber;Shop;Price
123455;Shop1;50
123455;Shop2;51

等等

编辑:正如我在评论中所说,您也可以这样做(这只是伪代码,我没有打开 c#)

class PriceForArticle
    int articleNumber;
    string shopName;
    float price;

然后您将使用此方法将它们初始化为 PriceForArticle 列表

List<PriceForArticle> prices = new List<PriceForArticle>();

for(int j = 1; j < AllArticles.Length; j++)
    for(int i = 1; i < AllArticles[j].Length; i++)
        prices.Add(new PriceForArticle(AllArticles[j][0], AllArticles[0][i], AllArticles[j][i]));
    

【讨论】:

文件格式已设置,这就是我无法更改它的原因。这种方式应该很简单,但是我无法更改文件格式。 您知道您将拥有多少家商店或者商店数量是可变的吗? 目前我只有7个,但将来会更多。 您可能会创建一个包含 ArticleNumber、商店(或名称或 ID,等等)和价格的类。然后使用 for 循环,遍历 csv 列表中的每个文章编号,并为它们循环遍历商店,将它们初始化为类的对象,然后将它们添加到列表中 我要试一试,虽然我试过但没有成功。

以上是关于如何使用 CsvHelper 解决 CSV 映射问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 CsvHelper 将 CSV 文件中的编号列映射到数组

C# CSVhelper 无法使用自定义映射编写

如何使用 csvhelper 将数据插入位列?

CSVHelper 在读取 csv 之前更改/操作标题

如何使用 CSVHelper 更新现有 CSV 文件中特定列中的值?

使用 CsvHelper 读取多头 CSV 文件