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

时间:2018-06-15 12:28:41

标签: csvhelper

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

我已经在我的地图中尝试了这个:

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。)

1 个答案:

答案 0 :(得分:1)

这确实是一个偏好问题。在映射中执行所有操作都很好。内联它也很好。另一个选项而不是ConvertUsing是创建自定义类型转换器。您可以使用其中一个内置的示例。 https://github.com/JoshClose/CsvHelper/blob/master/src/CsvHelper/TypeConversion/BooleanConverter.cs

GetRecords<T>()会返回IEnumerable<T>yield个记录。这意味着它只会在每次迭代中拉出一条记录,因此您不必担心内存中的所有数据。如果您执行ToList()Count()之类的操作,它会将所有记录拉入内存,因此请小心。