编写 CSV 文件 - 为列名添加前缀

Writing a CSV file - adding a prefix to the column names

在 CSV 文件中写入 collection 我想添加一个 属性 值作为列名的前缀。 有没有一种方法可以将映射器配置为使用 属性 值写入列名,如下例所示。

csv 文件

属性,身份证,123_Property1,123_Property2,身份证,456_Property1,456_Property2

标题,123,约翰,史密斯,456,海伦,汤姆森

public class MyClass
    {
      public string Property {get; set;}
      public List<MyCustom> MyCustoms {get; set;}
    }

   public class MyCustom 
        {
           public string Id {get; set;}
           public string Property2 {get; set;}
           public string Property3 {get; set;}
         }

 public class MyClassMap : ClassMap<MyClass>
 {
   public MyClassMap(){
   this.Map(m => m.Property).Name("Property"); 
(?)this.Map(m => m.MyCustoms).Name("IdVALUE ...");
  }

你想做的都能做,但它做了一些假设,很容易被打破。最终您应该重新考虑您的 CSV 结构。此解决方案手动写入 header 记录并使用自定义 TypeConverter 打印出每个 MyCustom class。

假设

  • 每个 MyClass 将具有相同数量的 MyCustom 并且 ID 将在每个 MyClass 记录之间匹配。
  • MyCustom Id 每次都会以相同的顺序打印出来。(更新:添加 OrderBy 以解决此问题。)
public static void Main(string[] args)
{    
    var records = new List<MyClass> {
        new MyClass {
            Property = "Title",
            MyCustoms = new List<MyCustom> {
                new MyCustom { Id = "123", Property1 = "John", Property2 = "Smith" },
                new MyCustom { Id = "456", Property1 = "Helen", Property2 = "Thomson"}
            }
        },
        new MyClass {
            Property = "AnotherProperty",
            MyCustoms = new List<MyCustom> {
                new MyCustom { Id = "123", Property1 = "Another11", Property2 = "Another12" },
                new MyCustom { Id = "456", Property1 = "Another21", Property2 = "Another22"}
            }
        }
    };

    using (var csv = new CsvWriter(Console.Out))
    {
        csv.Configuration.TypeConverterCache.AddConverter<List<MyCustom>>(new MyTypeConverter());
        csv.Configuration.HasHeaderRecord = false;

        // Get all of the ids from the first record.
        var ids = records[0].MyCustoms.OrderBy(m => m.Id).Select(m => m.Id).ToList();

        csv.WriteField("Property");

        foreach (var id in ids)
        {
            csv.WriteField("Id");
            csv.WriteField($"{id}_Property1");
            csv.WriteField($"{id}_Property2");
        }

        csv.NextRecord();

        csv.WriteRecords(records);                
    }

    Console.ReadKey();
}


public class MyClass
{
    public string Property { get; set; }
    public List<MyCustom> MyCustoms {get;set;}
}

public class MyCustom
{
    public string Id { get; set; }
    public string Property1 { get; set; }
    public string Property2 { get; set; }
}

private class MyTypeConverter : DefaultTypeConverter
{
    public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
    {
        var list = ((List<MyCustom>)value).OrderBy(m => m.Id).ToList();

        foreach (var item in list)
        {
            row.WriteField(item.Id);
            row.WriteField(item.Property1);
            row.WriteField(item.Property2);
        }

        return null;
    }
}