たいちょーの雑記

ぼくが3日に一度くらい雑記をかくところ

EntityFramework7でFileInfoをカラムにしたい

大したネタじゃないけども、すぐ忘れるので…。雑記です


何かしらのデータとローカルマシン内のデータへのファイルパスをDBで管理したい場面がありました。例えばですが、rowをC#で書くと以下みたいな感じです

class AudioFile {
  public string Title { get; set; }
  public string FilePath {get; set; }
}

パスは文字列だからstringでもいいのですが、存在チェックとかのためにFileInfoになっていると嬉しいです(たぶん)。つまり以下のようにしたいです。

class AudioFile {
  public string Title { get; set; }
  public FileInfo File { get; set; }
}

でもDBはFileInfoなんて型は知らないし、EF6もよしなにしてくれないようです(定義済みのコンバータ)

ちなみに今回DBはMySQL 8.0.31を使っているとします。

HasConversionでコンバータを定義してあげる

DbContextOnModelCreating(ModelBuilder)で変換を定義してあげる方法です。

public class Repository : DbContext {
// コンストラクタとかは省略

  public DbSet<AudioFile> AudioFiles => Set<AudioFile>();

  protected override void OnModelCreating(ModelBuilder modelBuilder) {
    base.OnModelCreating(modelBuilder);
    modelBuilder.Entity<AudioFile>(builder => {
        builder
            .Property(a => a.File)
            .HasConversion(fileInfo => fileInfo.FullName, str => new FileInfo(str));
    })
  }
}

とてもシンプル。ちなみにカラムの型はlongtextになる

クラスにプロパティを書く

string FilePathを参照してFileInfoを返すプロパティを定義するだけでもよさそう

class AudioFile {
  public string Title { get; set; }
  public string FilePath {get; set; }

  private FileInfo? fileInfo = null;
  [NotMapped]
  public FileInfo File {
    get {
      if(fileInfo is null) fileinfo = new FileInfo(FilePath);
      return fileInfo
    }
  }
}

まとめ

  • OnModelCreatingHasConversionを使って型変換を書ける
  • でもそもそもプロパティでもよさそう
  • 存在確認ならFile.Exists(string)でもいいので、stringで持っててもよさそう