CsvHelper 动态列映射

Posted

技术标签:

【中文标题】CsvHelper 动态列映射【英文标题】:CsvHelper dynamic column mapping 【发布时间】:2021-12-21 17:24:33 【问题描述】:

我正在按照此示例将自定义列名称映射到我的类模型:

CsvHelper Mapping by Name

在这个特定的部分:

public FooMap()

    Map(m => m.Id).Name("ColumnA");
    Map(m => m.Name).Name("ColumnB");

是否可以使用字符串作为列名而不是硬编码?像这样的——

public FooMap()

    Map("Col1").Name("ColumnA");
    Map("Col2").Name("ColumnB");

“Col1”和“Col2”是我的类模型的属性。我曾尝试使用反射,但它不起作用:

Map(x => typeof(MyClassModel).GetProperty("Col1")).Name("ColumnA");

如果我想要实现的目标可行,请告诉我。一些附加信息——列映射(源和目标)都存储在一个表中。

谢谢!

【问题讨论】:

根据经验,我认为不使用代码生成器在运行时创建ClassMap 是不可能的。 感谢杰伊的回复。现在,我只是手动将我的类模型中的每一列映射到一个自定义名称。有很多领域!这就是为什么我想知道我是否可以使用动态名称并只使用一个循环来映射所有列。再次感谢。 【参考方案1】:

这应该允许您使用字符串来映射属性名称和标题名称。

void Main()

    var mapping = new Dictionary<string, string>
    
        "Id","FooId",
        "Name","FooName"
    ;
    
    using (var reader = new StringReader("FooId,FooName\n1,Jordan"))
    using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
    
        var fooMap = new DefaultClassMap<Foo>();

        fooMap.Map(mapping);
        
        csv.Context.RegisterClassMap(fooMap);
        
        var records = csv.GetRecords<Foo>().ToList();
       


public static class CsvHelperExtensions

    public static void Map<T>(this ClassMap<T> classMap, IDictionary<string, string> csvMappings)
    
        foreach (var mapping in csvMappings)
        
            var property = typeof(T).GetProperty(mapping.Key);

            if (property == null)
            
                throw new ArgumentException($"Class typeof(T).Name does not have a property named mapping.Key");
            

            classMap.Map(typeof(T), property).Name(mapping.Value);
        
    


public class Foo

    public int Id  get; set; 
    public string Name  get; set; 


【讨论】:

这正是我想要的,非常感谢!【参考方案2】:

作为另一种方法,定义一个 XML/JSON 配置文件,您可以在其中定义要映射的列。编写一个解析器,它可以解析您的 XML/JSON 配置并返回要动态映射的列。这种方法允许您动态映射任何列,而无需重新编译您的代码。

【讨论】:

我的列映射已经在一个表中。我的问题是不知道如何将源列和目标列作为变量动态化。您有 XML/JSON 映射的代码示例吗?谢谢!

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

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

实体框架 + ODATA + 动态列映射

Azure Synapse 映射数据流 - 派生列中列名的动态映射

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

如何基于查找数据框创建数据框并在特定列中的动态和映射值上创建多列

如何在 C# 中使用 csvHelper 将两个单独列中的日期和时间合并到一个新的日期时间列中