2016-09-30 323 views
9

比方說,我有以下2種型號:EF核心的一個一對多的關係HasOne()WithMany()VS的hasMany()WithOne()

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); 

,如果有一個diffrence,是什麼呢?我應該寫兩個還是隻寫一個?

附註:我是否必須定義外鍵?根據我對數據庫的瞭解,不能在沒有外鍵的情況下創建關係,但EF不要求您有外鍵字段。那麼EF如何在不知道外鍵的情況下處理關係?它會導致性能下降或錯誤?

回答

5

你是對的,你可以在DbContext中創建關係而無需在數據庫中使用外鍵。

另外:

WithOne一對一的關係對雙方參考導航屬性。它們遵循與一對多關係相同的約定,但是在外鍵屬性上引入了唯一索引,以確保只有一個依賴關係與每個主體關聯。

許多一對多關係沒有一個實體類來表示連接表尚不支持。但是,您可以通過包含連接表的實體類並映射兩個單獨的一對多關係來表示多對多關係。

您只需要定義一個關係,因爲在某些情況下,您將創建一個沒有導航屬性(一個或集合)的父子關係。

對於示例:您添加關係的博客 - >帖子,因爲你必須在這兩個對象的導航性能,兩行做出相同的,但在不同的方式:

  • 博客 - >帖子(父 - >子)
  • 帖子 - >博客(子 - >父)
+1

那麼你是說這兩種方法之間沒有區別,哪種方式可以用同樣的方式使用模型?但使用HasOne()。WithMany更好? – soorena12

+0

在這種情況下,沒有更好的方法,它們只是創建兩個對象之間關係的不同方式,通常是從子項到父項的映射 –

+1

「您可以在DbContext中創建關係,而無需在數據庫中創建外鍵」。這是不正確的。 EF會引入一個影子屬性,它不在你的模型中,但會在數據庫中。 – Knelis

2

你可以定義你的模型沒有一個外鍵屬性。但是,實體框架將引入一個影子屬性,該屬性將位於數據庫中。

按照documentation

雖然建議具有從屬實體類中定義的外鍵的屬性,它不是必需的。如果未找到外鍵屬性,則會引入影子外鍵屬性,名稱爲<navigation property name><principal key property name>(有關更多信息,請參見Shadow Properties)。

+0

它不會「在數據庫中」,而是在EF Core中的實體定義中。 – Doug

+0

它肯定會在數據庫中。同樣,根據文檔:當數據庫中有數據不應該在映射的實體類型中公開時,Shadow屬性非常有用。它們通常用於外鍵屬性,其中兩個實體之間的關係由數據庫中的外鍵值表示,但是使用實體類型之間的導航屬性在實體類型上管理關係。「 – Knelis

+0

陰影屬性是一個實體框架概念,而不是數據庫概念。所以不,他們不是「在數據庫中」。我提到這只是爲了澄清任何人研究這個話題。 – Doug