プログラムを中心とした個人的なメモ用のブログです。 タイトルは迷走中。
内容の保証はできませんのであしからずご了承ください。

2019/03/04

EFCore で enum を文字列として保存・取得する

event_note2019/03/03 23:28

Entiry Framework Core で enum のプロパティを文字列型のカラムに保存・取得する方法です。

デフォルトだと enum は数値として格納されるので、値の変換を定義する必要があります。

環境

  • Visual Studio 2017
  • .NET Core 2.1

モデル

以下のようなクラスを例とします。

enum Gender
{
    Male,
    Female,
    Unknown
}

enum Birthplace
{
    Japan
}

class Person
{
    public int PersonId { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public Gender Gender { get; set; }
    public Birthplace Birthplace { get; set; }
}

DbContext と値の変換

DbContext を継承したクラスを作成します。
尚、ここでは SQL Server を使用する場合を想定して OnConfiguring をオーバーライドしています。

本題の、 enum を文字列として保存・取得するための値の変換を行うために OnModelCreating を以下のようにオーバーライドします。

class PersonDbContext : DbContext
{
    public DbSet<Person> Persons { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("接続文字列");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder
            .Entity<Person>()
            .Property(e => e.Gender)
            .HasConversion(
                v => v.ToString(),
                v => (Gender)Enum.Parse(typeof(Gender), v));
        modelBuilder
            .Entity<Person>()
            .Property(e => e.Birthplace)
            .HasConversion(
                v => v.ToString(),
                v => (Birthplace)Enum.Parse(typeof(Birthplace), v));
    }
}

実行結果

試しに以下のように実行してみた結果です。

// データベースの作成
using (var db = new PersonDbContext())
{
    db.Database.EnsureCreated();
}

// データの追加
using (var context = new PersonDbContext())
{
    var person = new Person
    {
        Name = "Hoge",
        Age = 30,
        Gender = Gender.Male,
        Birthplace = Birthplace.Japan
    };

    context.Persons.Add(person);
    context.SaveChanges();
}

Visual Studio のサーバーエクスプローラーで確認した結果です。
列挙型に対応するカラムの型が文字列で作成されています。