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

Posted

技术标签:

【中文标题】C# CSVhelper 无法使用自定义映射编写【英文标题】:C# CSVhelper unable to write using a custom mapping 【发布时间】:2022-01-11 15:54:33 【问题描述】:

我最近从 CSVHelper 版本 16.0.0 迁移到 27.2.1。在我看来,对于 CSV 编写器,映射丢失了,因为它们现在包含在 CSVContext 中,而不是 CSVConfiguration 中。

我想使用自定义映射来写入 CSV 而不是自动生成的映射,现在有办法做到这一点吗?

using (StreamWriter _stream = new StreamWriter(_fileLocation))

  using (CsvWriter _csvWriter = new CsvWriter(_stream, CsvContext.Configuration))
  
      _csvWriter.WriteRecords(items);
      _csvWriter.Flush();
  

我将代码添加为上下文,您可以看到CSVWriter 只接受不再包含映射的配置,所以当我检查CSVWriter 的上下文时,没有映射。如果我检查CSVContextitself,我确实看到了一个映射,即我之前制作的自定义映射。

示例:

public class Foo

    public Guid id get;set;   
    public string name get;set;
    public DateTime created get;set;

假设我有上面的 Foo 类,我使用工厂创建了一个自定义类映射:

private static ClassMap CreateMap()

    Factory _factory = new Factory();
            
    IHasMap<Foo> _mapper = _factory.CreateClassMapBuilder<Foo>();       
    
    _mapper.Map(x => x.id);
    _mapper.Map(x => x.name);       
    
    return _mapper.Build();
   

然后我这样注册映射:

_context.RegisterClassMap(CreateMap());

我会得到结果:

Id,name,Date
d2e0b6d5-356c-4c34-9437-92942ee9232c,SomeName,2020-01-01

但我想要的结果是:

Id,name
d2e0b6d5-356c-4c34-9437-92942ee9232c,SomeName

我想澄清一件事,这是在 16.0.0.0 版本下工作的

【问题讨论】:

你检查过documentation吗? ClassMap&lt;T&gt; 必须在上下文中注册,但它应该像以前一样工作。否则请做一个小例子,包含具有 2 或 3 个示例值的源类和所需的 CSV 输出。 我一直在使用上下文的RegisterClassMap方法。当我使用版本 16.0.0.0 时,它可以按我的意愿工作(当 `RegisterClassMap~ 是配置的一部分时)。我会尽力给出一个抽象的例子来说明我的代码发生了什么。 【参考方案1】:

RegisterClassMapConfiguration 移动到 Context。您必须在CsvWriter.Context 上注册。

public static void Main(string[] args)
    
    var config = new CsvConfiguration(CultureInfo.InvariantCulture)
    
        // Configuration settings
    ;
    
    using (CsvWriter _csvWriter = new CsvWriter(Console.Out, config))
    
        var fooRecords = new List<Foo>  new Foo  id = new Guid("d2e0b6d5-356c-4c34-9437-92942ee9232c"), name = "SomeName", created = new DateTime(2020,1,1) ;

        _csvWriter.Context.RegisterClassMap(CreateMap());

        _csvWriter.WriteRecords(fooRecords);

        _csvWriter.Flush();
        
        Console.Read();
                


public class Foo

    public Guid id get;set;   
    public string name get;set;
    public DateTime created  get; set; 


private static ClassMap CreateMap()

    Factory _factory = new Factory();

    IHasMap<Foo> _mapper = _factory.CreateClassMapBuilder<Foo>();

    _mapper.Map(x => x.id);
    _mapper.Map(x => x.name);

    return _mapper.Build();

【讨论】:

谢谢,我做了一个明显愚蠢的疏忽,在 CsvWriter 初始化后不做映射。如果你能在构造函数中立即包含上下文就好了,我不知道是否有原因没有这样做? 我认为这些更改与性能或线程问题有关。我不确定版本 20.0.0 中的更改是否可以在上下文中传递。 joshclose.github.io/CsvHelper/change-log/#section-32

以上是关于C# CSVhelper 无法使用自定义映射编写的主要内容,如果未能解决你的问题,请参考以下文章

CsvHelper 动态列映射

C# CsvHelper:WriteRecord 抛出“ConfigurationException:不能自动映射继承 IEnumerable 的类型”

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

将 CsvHelper 自定义转换器应用于一组类的所有字符串属性

使用CsvHelper写入数据时出现异常

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