【问题标题】:Include RawRecord in dynamic objects returned from CsvHelper GetRecords在从 CsvHelper GetRecords 返回的动态对象中包含 RawRecord
【发布时间】:2020-02-03 22:01:11
【问题描述】:

当我使用Configuration.RegisterClassMap 转换为 Class 对象时,我有这个工作(本质上,我将 row.Context.RawRecord 映射到我的 Class 上名为 RawRecord 的属性):

public sealed class RecordMap : ClassMap<CsvRecord>
{
    public RecordMap()
    {
        AutoMap(CultureInfo.CurrentCulture);
        Map(m => m.RawRecord).ConvertUsing(row => row.Context.RawRecord.Replace("\r\n", ""));
    }
}

...但我想不再需要类对象(在此示例中为 CsvRecord),而是使用带有 csv.GetRecords&lt;dynamic&gt;() 的动态对象。这对我有用,只是我无法弄清楚如何获得RawRecord。理想情况下,如果我可以添加一些配置以简单地将其添加为动态对象上的新列,但我找不到类似的东西。

我正在使用 linq 构建域对象列表 (Individuals),其中包括对 CSV 行进行分组,因此我不想手动遍历每条记录:

using (var csv = new CsvReader(reader, CultureInfo.CurrentCulture))
{
    csv.Configuration.PrepareHeaderForMatch = (string header, int index) => Regex.Replace(header, "[^A-Za-z0-9]", "");

    var dateUpdated = DateTime.UtcNow;
    var individuals = csv.GetRecords<dynamic>().ToList().Where(r => r.GroupType == "Individual").
        GroupBy(r => r.GroupID).
        Select(g => new Individual(
            // Include constructor arguments here
            g.Key,
            g.First().Name1
            // ...
            // Include an array of all raw CSV records that have been used to generate this object
            // This currently fails
            g.Select(r => r.RawRecord).Cast<string>().ToArray()
        )).ToList();
}

【问题讨论】:

    标签: csvhelper


    【解决方案1】:

    我不相信有办法通过配置来做到这一点。

    using (var csv = new CsvReader(reader, CultureInfo.CurrentCulture))
    {
        csv.Configuration.PrepareHeaderForMatch = (string header, int index) => Regex.Replace(header, "[^A-Za-z0-9]", "");
    
        csv.Read();
        csv.ReadHeader();
    
        var records = new List<dynamic>();
    
        while (csv.Read())
        {
            var record = csv.GetRecord<dynamic>();
            record.RawRecord = csv.Context.RawRecord.Replace("\r\n", "");
            records.Add(record);
        }
    
        var dateUpdated = DateTime.UtcNow;
        var individuals = records.Where(r => r.GroupType == "Individual").
            GroupBy(r => r.GroupID).
            Select(g => new Individual(
                // Include constructor arguments here
                g.Key,
                g.First().Name1
                // ...
                // Include an array of all raw CSV records that have been used to generate this object
                // This currently fails
                g.Select(r => r.RawRecord).Cast<string>().ToArray()
            )).ToList();
    }
    

    【讨论】:

    • 谢谢大卫。是的,我想我可能只是用csv.Read() 循环遍历CSV(我看到了一些例子),但我真的希望有一些更优雅的东西。我假设这不会对性能产生太大影响(csv.GetRecords 无论如何都需要在内部进行循环),但它只会使代码不那么简洁。也就是说,您的示例确实解决了问题,非常感谢您的响应和代码示例。
    • 是的 csv.GetRecords 在内部使用 csv.GetRecord 循环。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-30
    • 2017-06-06
    相关资源
    最近更新 更多