CsvHelper - 在读取记录时执行逻辑

CsvHelper - Perform logic while reading records

我想在读取文件时应用逻辑,例如清理一串特殊字符,或者如果字段为空则确定两个日期之间的差异。

我已经在我的地图上试过了:

public InboundPlacementMap()
    {
        AutoMap();
        Map(m => m.HomePhone).ConvertUsing(
            rec =>
            {
                return CleanPhoneNumber(rec.HomePhone);
            });

        Map(m => m.LengthOfStay).Name("Length of Stay").ConvertUsing(
            row =>
            {
                if (row.LengthOfStay > 0)
                    return (int)row.LengthOfStay;
                return (row.AdmitDate - row.DischargeDate+500).Days;
            });
    }

    private string CleanPhoneNumber(string phone)
    {
        //Do some logic to remove characters, etc.
        return phone;
    }

(实际上,CleanPhoneNumber 位于跨项目使用的不同库中。)但是调用它有一种我不喜欢的味道,而且它似乎不起作用:

 Map(m => m.PatHomePhone).ConvertUsing(rec =>
    { return PamUtility.Utilities.CleanPhoneNumber(rec.PatHomePhone); });

在我阅读的方法中,我使用 GetRecords<>() 一次阅读所有内容。我最好逐条阅读记录,并在阅读每一条记录后执行我的逻辑吗? (这对我来说似乎很混乱。)

            List<InboundPlacementFileRecord> allRecords = new List<InboundPlacementFileRecord>();
        using (TextReader textReader = File.OpenText(fileToRead))
        {
            var csv = new CsvReader(textReader);
            csv.Configuration.Delimiter = "|";
            csv.Configuration.IgnoreBlankLines = true;
            csv.Configuration.PrepareHeaderForMatch = 
                        header => header.Replace(" ", string.Empty);
            csv.Configuration.HeaderValidated= null;
            csv.Configuration.MissingFieldFound = null;
            csv.Configuration.RegisterClassMap<InboundPlacementMap>();
            allRecords = csv.GetRecords<InboundPlacementFileRecord>().ToList();
        }

编辑: 作为参考,这是逐个记录的样子,如果要执行更多逻辑,它会很快变得丑陋,因此我希望将其放入映射中:

            while (csv.Read())
            {
                var record = csv.GetRecord<InboundPlacementFileRecord>();

                record.LengthOfStay=(record.LengthOfStay>0)? record.LengthOfStay : 
                    (int)(record.DischargeDate-record.AdmitDate).TotalDays;

                // ... other logic here ...

                allRecords.Add(record);
            }

(在提出这个问题时使用最新的 CsvHelper,7.1.0。)

这真的是一个偏好问题。在映射中做所有事情都很好。在线执行也很好。替代 ConvertUsing 的另一种选择是创建自定义类型转换器。您可以使用其中一个内置的作为示例。 https://github.com/JoshClose/CsvHelper/blob/master/src/CsvHelper/TypeConversion/BooleanConverter.cs

GetRecords<T>() returns 一个 IEnumerable<T>yield 记录。这意味着它只会在每次迭代中提取一条记录,因此您不必担心所有数据都在内存中。如果你做类似ToList()Count()的操作,它会将所有记录拉入内存,所以要小心。