0
0

EntityFrameWorkで同じテーブルに対して1対Nを複数つくる方法

Last updated at Posted at 2024-05-09

どうやったらタイトルがわかりやすくなるか考えたがどう説明したらよいかわからなかったので
暫定でつけました。

初心者なので
・こんな無駄なことする必要ない
・データベースの作り方が悪いだけ
などいろいろあると思いますが、EntityFrameWorkが自動で処理してくれたので
情報としてあげておくと何か別の用途で使えるかもということで上げておくことにしました。

結局どういうことかというと例えば
ParentクラスとChildクラスがあって、(テーブルもParentとChildの2テーブル)
Parentクラス内に男の子と女の子のListを作ってそれをリレーションとして定義するという感じです。

//こんな感じ でもこれでは動きません。
public class Parent{
    public int ParentId;
    public List<Child> Boys { get; set; } = new();
    public List<Child> Girls{ get; set; } = new();
}

public class Child{
    public int ChileId;
    public string Name;
    public int ParentId;
}

//以下はコンテキスト内
public DbSet<Child>? Child { get; set; }
modelBuilder.Entity<Child>()
    .HasOne(c => c.Parent)
    .WithMany(p => p.Boys)
    .HasForeignKey(c => c.ParentId);

modelBuilder.Entity<Child>()
    .HasOne(c => c.Parent)
    .WithMany(p => p.Girls)
    .HasForeignKey(c => c.ParentId);

つまり、男の子と女の子を同じテーブルに入れて、親からみたら登録、呼び出しは
Boys、Girlsを使えばよいという状態です。BoysとGirlsはゲッターとセッターでChildテーブルから自分でフィルターしたらよいのではと思いますが、それはなしですべてEntityFrameWorkに処理させる方法の説明になります。

結論からするとChildの派生クラスでGirlsとBoysを作ってやるとEntityFrameWorkがChildのテーブルにDiscriminatorというカラムを追加して処理してくれるみたいです。どうやら
https://learn.microsoft.com/ja-jp/ef/core/modeling/inheritance#table-per-hierarchy-and-discriminator-configuration
に書いてるらしいです。
これに従うと今回の例の場合

public class Parent{
    public int ParentId;
    public List<Boy> Boys { get; set; } = new();
    public List<Girl> Girls{ get; set; } = new();
}
public class Boy :Child{
}
public class Girl : Child{
}
public class Child{
    public int ChileId;
    public string Name;
    public int ParentId;
}

//以下はコンテキスト内
public DbSet<Girl>? Girls { get; set; }
public DbSet<Boy>? Boys{get;set;}

modelBuilder.Entity<Boy>()
    .HasOne(c => c.Parent)
    .WithMany(p => p.Boys)
    .HasForeignKey(c => c.ParentId);

modelBuilder.Entity<Girl>()
    .HasOne(c => c.Parent)
    .WithMany(p => p.Girls)
    .HasForeignKey(c => c.ParentId);

とするとテーブルはBoysテーブル、GirlsテーブルではなくChildテーブルができる形で、ParentからBoysに登録するとChildテーブルのDiscriminatorカラムにBoyという文字列付で登録され、呼び出すとやはりBoyという文字列が付いた行だけが取り出せます。
自分のソースからParentとChildに書き換えたのでもしかするとどこか置換ミスがあって動かないかもしれませんが、これが必要な方には簡単に修正できると思いますのでご勘弁を。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0