C# CSVHelper-将带有可变标题的CSV映射到对象

C# CSVHelper-将带有可变标题的CSV映射到对象,c#,csv,mapping,csvhelper,C#,Csv,Mapping,Csvhelper,我正在尝试将一些可变格式选项卡分隔的文件映射到我的类Foo: public class Foo { public string A { get; set; } public int? B { get; set; } public double? C { get; set; } } 文件1: A B C string 1 1.0 文件2: Bee Sea 1 1.0 当标题格式为常量时,使用CsvClassMap使用CsvHelper很容易做到这一点

我正在尝试将一些可变格式选项卡分隔的文件映射到我的类Foo:

public class Foo
{
    public string A { get; set; }
    public int? B { get; set; }
    public double? C { get; set; }
}
文件1:

A   B   C
string  1   1.0
文件2:

Bee Sea
1   1.0
当标题格式为常量时,使用CsvClassMap使用CsvHelper很容易做到这一点:

public sealed class FooMap : CsvClassMap<Foo>
{
    public FooMap()
    {
        Map(x => x.A).Name("A");
        Map(x => x.B).Name("B");
        Map(x => x.C).Name("C");
    }
}
公共密封类FooMap:CsvClassMap
{
公共地图()
{
Map(x=>x.A).Name(“A”);
映射(x=>x.B).Name(“B”);
映射(x=>x.C).Name(“C”);
}
}
但是,当标题格式可变时,这会变得复杂

  • 文件的宽度和高度可以不同
  • 标题顺序不是固定的
  • 每个文件最多只能定义一次属性
  • 每个属性都可以与各种头名称相关
  • 标题名称仅限于单个属性
  • 并非所有属性都必须在文件中定义
映射到此对象的最佳方式是什么

我设想我将在headers列上用唯一的键填充headers到properties的映射表,然后查找每个header各自的属性

目前的调查方向:

public sealed class FooMap : CsvClassMap<Foo>
{
    public FooMap()
    {
    }

    public void SetHeaders(List<string> headers)
    {
        var dictionary = new Dictionary<string, List<string>>();
        dictionary.Add("A", new List<string>() { "A", "Aay" });
        dictionary.Add("B", new List<string>() { "B", "Bee" });
        dictionary.Add("C", new List<string>() { "C", "Sea" });

        ...

    }
}
公共密封类FooMap:CsvClassMap
{
公共地图()
{
}
公共void集合标题(列表标题)
{
var dictionary=newdictionary();
Add(“A”,newlist(){“A”,“Aay”});
添加(“B”,新列表(){“B”,“Bee”});
添加(“C”,新列表(){“C”,“Sea”});
...
}
}

您可以为每个属性指定多个名称,并使其在缺少字段时不会引发异常

以下是使用LINQPad的示例:

void Main()
{
    using (var stream = new MemoryStream())
    using (var writer = new StreamWriter(stream))
    using (var reader = new StreamReader(stream))
    using (var csv = new CsvReader(reader))
    {
        writer.WriteLine("A Bee C");
        writer.WriteLine("string    1   1.0");
        writer.Flush();
        stream.Position = 0;

        csv.Configuration.Delimiter = " ";
        csv.Configuration.WillThrowOnMissingField = false;
        csv.Configuration.RegisterClassMap<FooMap>();
        csv.GetRecords<Foo>().ToList().Dump();
    }
}

public class Foo
{
    public string A { get; set; }
    public int? B { get; set; }
    public double? C { get; set; }
    public Guid? D { get; set; }
}

public class FooMap : CsvClassMap<Foo>
{
    public FooMap()
    {
        Map( m => m.A ).Name( "A", "Aay" );
        Map( m => m.B ).Name( "B", "Bee" );
        Map( m => m.C ).Name( "C", "Sea" );
        Map( m => m.D ).Name( "D", "Dee" );
    }
}

这些文件在某种程度上有相似的格式吗?例如:所有文件至少包含字段A和B。@raidensan最有可能,但不一定。不过,这些文件将是相同的对象,只是在没有匹配列的情况下使用空值。
A: string
B: 1
C: 1
D: null