3

次のような構造の CSV ファイルがあります。

Header1,Header2,Header3 
1,2,3 
5,,6 
4,4,4

Josh Close の CsvHelper を使用し、次のように呼び出す場合GetRecords<T>:

List<TestData> data = csvReader.GetRecords<TestData>();

データのリストには 2 行目が含まれていません。設定をいじって、空の文字列を受け入れ、空の場合は「0」を返すダブルコンバーターを実装しようとしましたが、行はまだ破棄されます。各フィールドの手動取得を回避しようとしています。ただし、行ごとのソリューション、つまりcsvReader.GetRecord<TestData>()ループにネストされたソリューションにはまだ満足しています。

次のテストコードがあります。

public class When_importing_csv_with_missing_filed
{
    [Test]
    public void Dont_discard_the_row_with_missing_field()
    {
        using (TextReader textReader = new StreamReader("Test.csv"))
        {
            Assert.IsTrue(File.Exists("Test.csv"));
            var reader = new CsvReader(textReader);
            reader.Configuration.RegisterClassMap<TestMap>();
            reader.Configuration.IgnoreReadingExceptions = true;
            reader.Configuration.SkipEmptyRecords = false;
            List<TestData> testData = reader.GetRecords<TestData>().ToList();
        }
    }
}

public class TestMap : CsvClassMap<TestData>
{
    public override void CreateMap()
    {
        Map(m => m.Header1).Name("Header1").TypeConverter<DoubleConverter>();
        Map(m => m.Header2).Name("Header2").TypeConverter<NullValueTypeConverter>();
        Map(m => m.Header3).Name("Header3").TypeConverter<DoubleConverter>();
    }
}

public class NullValueTypeConverter : DoubleConverter
{
    public override object ConvertFromString(TypeConverterOptions options, string text)
    {
        return String.IsNullOrEmpty(text) ? 0 : base.ConvertFromString(options, text);
    }

    public override bool CanConvertFrom(Type type)
    {
        return type == typeof(string);
    }
}

public class TestData
{
    public double? Header1 { get; set; }
    public double? Header2 { get; set; }
    public double? Header3 { get; set; }
}

あなたに..

4

1 に答える 1

1

これは私にとっては完全にうまくいくようです。

コード:

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( "Header1,Header2,Header3" );
        writer.WriteLine( "1,2,3" );
        writer.WriteLine( "5,,6" );
        writer.WriteLine( "4,4,4" );
        writer.Flush();
        stream.Position = 0;

        csv.Configuration.RegisterClassMap<TestMap>();
        csv.Configuration.IgnoreReadingExceptions = true;
        csv.Configuration.SkipEmptyRecords = false;
        var records = csv.GetRecords<TestData>().ToList();
        records.Dump();
    }

}

public class TestData
{
    public double? Header1 { get; set; }
    public double? Header2 { get; set; }
    public double? Header3 { get; set; }
}

public class TestMap : CsvClassMap<TestData>
{
    public override void CreateMap()
    {
        Map(m => m.Header1).Name("Header1");
        Map(m => m.Header2).Name("Header2");
        Map(m => m.Header3).Name("Header3");
    }
}

結果:

Header1 Header2 Header3
1       2       3
5       null    6
4       4       4
于 2014-04-10T20:05:38.460 に答える