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

时间:2019-05-18 20:25:32

标签: c# csvhelper

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

csv文件

属性,Id,123_Property1、123_Property2,Id,456_Property1、456_Property2

Title,123,John,Smith,456,Helen,Thomson

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 ...");
  }

1 个答案:

答案 0 :(得分:0)

您想做的事情可以完成,但是它有一些假设并且很容易被打破。最终,您应该重新考虑CSV结构。该解决方案手动写入标题记录,并使用自定义TypeConverter打印出每个MyCustom类。

假设

  • 每个MyClass将具有相同数量的MyCustom,并且每个MyClass记录之间的ID都将匹配。
  • 每次都会以相同的顺序打印出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;
    }
}