色んな事を書く

シンプルさを極めたエンジニアになりたい

CSV Helper で CSV の行を Deserialize したい

読み込んだ CSV のある Header の値を C# のクラスプロパティにマッピングさせて Deserialize したい場合がある。 そんなときの方法をメモ。

例として CSV で本の「タイトル」「著者」をまとめていたとして、これを C# の Book class に Deserialize する。

public class Book
{
    public string Title { get; init; }

    public string Author { get; init; }
}

環境は以下

  • net6.0
  • CsvHelper 30.0.1

Deserialize するクラスに Attribute を付ける

これが最もシンプルな方法かな。

using CsvHelper.Configuration.Attributes;

public class Book
{
    [Name("タイトル")]
    public string Title { get; init; }

    [Name("著者")]
    public string Author { get; init; }
}

このクラスを CsvReader の GetRecords の型パラメータに指定すると CSV ファイルの「タイトル」の値を「Title」に、「著者」の値を「Author」にマッピングして Deserialize してくれる。

ClassMap を使う

Attribute を付けたくないときは ClassMap を使う。

using CsvHelper.Configuration;


public class BookClassMapper: ClassMap<Book>
{
    public BookClassMapper()
    {
        Map(b => b.Title).Name("タイトル");
        Map(b => b.Author ).Name("著者");
    }
}

CsvReader.Context の RegisterClassMap の型パラメータにこのクラスを指定すると Attribute を指定した場合と同じ Deserialize 結果になる。

using var csvReader = new CsvReader(sr, new CsvConfiguration(CultureInfo.InvariantCulture)
{
    HasHeaderRecord = true
});
csvReader.Context.RegisterClassMap<BookClassMapper>();

CSV にヘッダーがないとどうなるの

例えば読み込む CSV のヘッダーに「タイトル」が含まれていないとすると Parse Exception が発生する。これの例外をバリデーションに使うなり出来る。