web-dev-qa-db-ja.com

EFコアの1対多の関係HasOne()。WithMany()vs HasMany()。WithOne()

次の2つのモデルがあるとします。

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public Blog Blog { get; set; }
}

DbContextでモデルの関係を構成したい場合、次のような違いがあります。

modelBuilder.Entity<Post>()
            .HasOne(p => p.Blog)
            .WithMany(b => b.Posts);

そして

modelBuilder.Entity<Blog>()
            .HasMany(b => b.Posts)
            .WithOne(p => p.blog);

違いがある場合、それは何ですか?両方を書くべきですか、それとも片方だけ書くべきですか?

補足:外部キーを定義する必要がありますか?データベースに関する私の知識に基づいて、外部キーなしでリレーションシップを作成することはできませんが、EFでは外部キーフィールドを持つ必要はありません。では、EFは外部キーを知らずにリレーションシップをどのように処理しますか?パフォーマンスの低下やバグの原因になりますか?

19
soorena12

そうです、データベースの外部キーなしでDbContextにリレーションを作成できます。

また:

WithOne1対1の関係には、両側に参照ナビゲーションプロパティがあります。これらは1対多の関係と同じ規則に従いますが、一意のインデックスが外部キープロパティに導入され、1つの依存関係のみが各プリンシパルに関連付けられるようにします。

多対多結合テーブルを表すエンティティクラスのない関係はまだサポートされていません。ただし、結合テーブルのエンティティクラスを含め、2つの個別の1対多リレーションシップをマッピングすることにより、多対多リレーションシップを表すことができます。

場合によっては、ナビゲーションプロパティ(1つまたはコレクション)なしで親子のリレーションを作成するため、リレーションを1つだけ定義する必要があります。

例:両方のオブジェクトにナビゲーションプロパティがあるため、Blog-> Postsのリレーションを追加します。2行は同じですが、異なる方法になります。

  • ブログ->投稿(親->子)
  • 投稿->ブログ(子->親)
10
H. Herzl

外部キープロパティなしでモデルを定義できます。ただし、Entity Frameworkはシャドウプロパティを導入します。これはデータベース内にあります。

ドキュメント によると:

依存エンティティクラスで外部キープロパティを定義することをお勧めしますが、必須ではありません。外部キープロパティが見つからない場合、<navigation property name><principal key property name>という名前のシャドウ外部キープロパティが導入されます(詳細については Shadow Properties を参照してください)。

2
Knelis