關聯性的簡介

本檔提供物件模型和關係資料庫中關聯性的表示法的簡單簡介,包括 EF Core 在兩者之間的對應方式。

物件模型中的關聯性

關聯性定義兩個實體彼此的關聯性。 例如,在部落格中建立文章模型化時,每個文章都會與其發佈的部落格相關,而部落格則與該部落格上發佈的所有文章有關。

在 C# 之類的面向物件語言中,部落格和文章通常以兩個類別表示: BlogPost。 例如:

public class Blog
{
    public string Name { get; set; }
    public virtual Uri SiteUri { get; set; }
}
public class Post
{
    public string Title { get; set; }
    public string Content { get; set; }
    public DateTime PublishedOn { get; set; }
    public bool Archived { get; set; }
}

在上述類別中,沒有任何可指出 BlogPost 相關的專案。 這可以加入至物件模型,方法是將參考從 Post 新增至 Blog 其發佈所在的 :

public class Post
{
    public string Title { get; set; }
    public string Content { get; set; }
    public DateOnly PublishedOn { get; set; }
    public bool Archived { get; set; }

    public Blog Blog { get; set; }
}

同樣地,相同關聯性的相反方向可以表示為每個 Blog上的物件集合Post

public class Blog
{
    public string Name { get; set; }
    public virtual Uri SiteUri { get; set; }

    public ICollection<Post> Posts { get; }
}

從和 Post 反轉BlogPost的這個連接Blog稱為 EF Core 中的「關聯性」。

重要

關聯性通常會以任一方向周遊。 在此範例中,即從 BlogPost 透過 Blog.Posts 屬性,以及從 Post 回到 BlogPost.Blog 屬性。 這是 一個 關聯性,而不是兩個。

提示

在 EF Core 中 Blog.Posts ,和 Post.Blog 屬性稱為「導覽」。

關係資料庫中的關聯性

關係資料庫代表使用外鍵的關聯性。 例如,使用 SQL Server 或 Azure SQL,下表可用來代表我們的 PostBlog 類別:

CREATE TABLE [Posts] (
    [Id] int NOT NULL IDENTITY,
    [Title] nvarchar(max) NULL,
    [Content] nvarchar(max) NULL,
    [PublishedOn] datetime2 NOT NULL,
    [Archived] bit NOT NULL,
    [BlogId] int NOT NULL,
    CONSTRAINT [PK_Posts] PRIMARY KEY ([Id]),
    CONSTRAINT [FK_Posts_Blogs_BlogId] FOREIGN KEY ([BlogId]) REFERENCES [Blogs] ([Id]) ON DELETE CASCADE);

CREATE TABLE [Blogs] (
    [Id] int NOT NULL IDENTITY,
    [Name] nvarchar(max) NULL,
    [SiteUri] nvarchar(max) NULL,
    CONSTRAINT [PK_Blogs] PRIMARY KEY ([Id]));

在此關係型模型中, PostsBlogs 數據表都會獲得「主鍵」數據行。 主鍵的值可唯一識別每個文章或部落格。 此外, Posts 數據表也會提供「外鍵」數據行。 主 Blogs 鍵數據行 Id 是由 BlogId 數據表的 Posts 外鍵數據行所參考。 此數據行為「限制」,因此的數據Posts行中的任何BlogId值都必須符合 數據行Blogs中的Id值。 此比對會決定每個文章與哪個部落格相關。 例如,如果 BlogId 數據表的一個數據列中 Posts 的值是 7,則該數據列所代表的文章會以主鍵 7 發佈在部落格中。

在 EF Core 中對應關聯性

EF Core 關聯性對應全都與將關係資料庫中所使用的主鍵/外鍵表示法對應至物件模型中所用對象之間的參考。

從最基本的意義上說,這牽涉到:

  • 將主鍵屬性新增至每個實體類型。
  • 將外鍵屬性新增至一個實體類型。
  • 將實體類型與主鍵與外鍵之間的參考產生關聯,以形成單一關聯性組態。

進行此對應之後,EF 會在對象之間的參考變更時視需要變更外鍵值,並在外鍵值變更時視需要變更對象之間的參考。

注意

主鍵用於對應關聯性以上。 如需詳細資訊,請參閱 密鑰

例如,上述實體類型可以使用主鍵和外鍵屬性來更新:

public class Blog
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual Uri SiteUri { get; set; }

    public ICollection<Post> Posts { get; }
}
public class Post
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public DateTime PublishedOn { get; set; }
    public bool Archived { get; set; }

    public int BlogId { get; set; }
    public Blog Blog { get; set; }
}

提示

主鍵和外鍵屬性不需要是實體類型的公開可見屬性。 不過,即使屬性已隱藏,請務必辨識它們仍存在於 EF 模型中。

Blog.Id的主鍵屬性和 、 的Blog外鍵屬性PostPost.BlogId,然後可以與實體類型 (Blog.PostsPost.Blog) 之間的參考 (“navigations”) 相關聯。 這樣建置簡單的關聯性時,EF 會自動完成這項作業,但在覆寫 OnModelCreatingDbContext方法時也可以明確指定。 例如:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .HasMany(e => e.Posts)
        .WithOne(e => e.Blog)
        .HasForeignKey(e => e.BlogId)
        .HasPrincipalKey(e => e.Id);
}

現在,所有這些屬性都會以一致的方式一起運作,以表示 和Post之間的Blog單一關聯性。

深入了解

EF 支援許多不同類型的關聯性,其中有許多不同方式可以表示和設定這些關聯性。 若要跳到不同類型的關聯性的範例,請參閱:

  • 一對多關聯性,其中單一實體與任意數目的其他實體相關聯。
  • 一對一關聯性,其中單一實體與另一個單一實體相關聯。
  • 多對多關聯性,其中任意數目的實體與任意數目的其他實體相關聯。

如果您不熟悉 EF,則嘗試上述項目符號點中連結的範例是了解關聯性運作方式的好方法。

若要深入瞭解關聯性對應所涉及的實體類型屬性,請參閱:

  • 關聯性的外鍵和主體索引鍵,其中涵蓋外鍵對應至資料庫的方式。
  • 關聯性導覽,其描述如何透過外鍵分層導覽,以提供關聯性面向對象檢視。

EF 模型是使用三種機制的組合來建置:慣例、對應屬性和模型產生器 API。 大部分範例都會顯示模型建置 API。 若要深入瞭解其他選項,請參閱:

  • 關聯性慣例,可探索實體類型、其屬性,以及類型之間的關聯性。
  • 關聯性對應屬性,可用來替代模型建置 API,以取得關聯性組態的某些層面。

重要

模型建置 API 是 EF 模型的最終事實來源,它一律優先於慣例或對應屬性所指定的組態。 這也是唯一具有完整精確度的機制,可設定EF模型的各個層面。

與關聯性相關的其他主題包括:

  • 串聯刪除,描述呼叫 或 SaveChangesAsyncSaveChanges,如何自動刪除相關的實體。
  • 擁有的實體類型 會使用特殊的「擁有」關聯性類型,這表示這兩種類型之間的連線比這裡所討論的「一般」關聯性更強。 這裡為正常關聯性描述的許多概念會延續到擁有的關聯性。 然而,擁有的關係也有他們自己的特殊行為。

使用關聯性

模型中定義的關聯性可以用各種方式使用。 例如: