Sdílet prostřednictvím


Úvod do relací

Tento dokument poskytuje jednoduchý úvod k reprezentaci relací v objektových modelech a relačních databázích, včetně toho, jak EF Core mapuje mezi nimi.

Relace v objektových modelech

Relace definuje, jak spolu dvě entity vzájemně souvisejí. Když například modelujete příspěvky v blogu, každý příspěvek souvisí s blogem, na který se publikuje, a blog se vztahuje ke všem příspěvkům publikovaným na tomto blogu.

V objektově orientovaném jazyce, jako je C#, jsou blog a příspěvek obvykle reprezentovány dvěma třídami: Blog a Post. Příklad:

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

Ve výše uvedených třídách není nic naznačovat, že Blog a Post jsou související. Můžete ho přidat do objektového modelu přidáním odkazu z Post publikovaného objektového Blog modelu:

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

Stejně tak může být opačný směr stejné relace reprezentován jako kolekce Post objektů na každém Blog:

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

    public ICollection<Post> Posts { get; }
}

Toto připojení z Blog Post a inverzního připojení Post z pozadí do Blog se v EF Core označuje jako "relace".

Důležité

Jedna relace se obvykle prochází v obou směrech. V tomto příkladu je to od Blog do Post vlastnosti Blog.Posts a zpět Post přes Blog Post.Blog vlastnost. Toto je jedna relace, ne dvě.

Tip

V EF Core se vlastnosti Blog.Posts označují Post.Blog jako "navigace".

Relace v relačních databázích

Relační databáze představují relace pomocí cizích klíčů. Například pomocí SQL Serveru nebo Azure SQL můžete k reprezentaci našich Post a Blog tříd použít následující tabulky:

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

V tomto relačním modelu Posts jsou tabulky a Blogs tabulky uvedeny ve sloupci "primární klíč". Hodnota primárního klíče jednoznačně identifikuje každý příspěvek nebo blog. Tabulka má navíc Posts sloupec "cizí klíč". Na Blogs sloupec primárního BlogId klíče odkazuje sloupec cizího Posts klíče tabulky.Id Tento sloupec je "omezený", aby jakákoli hodnota ve BlogId sloupci Posts musí odpovídat hodnotě Id ve sloupci Blogs. Tato shoda určuje, ke kterému příspěvku se každý příspěvek vztahuje. Pokud BlogId je například hodnota v jednom řádku Posts tabulky 7, pak se příspěvek reprezentovaný tímto řádkem publikuje na blogu s primárním klíčem 7.

Mapování relací v EF Core

Mapování relací EF Core se týká mapování reprezentace primárního klíče nebo cizího klíče použitého v relační databázi na odkazy mezi objekty použitými v objektovém modelu.

V nejzásadnějším smyslu to zahrnuje:

  • Přidání vlastnosti primárního klíče ke každému typu entity
  • Přidání vlastnosti cizího klíče do jednoho typu entity
  • Přidružení odkazů mezi typy entit k primárním a cizím klíčům pro vytvoření jedné konfigurace relace.

Po provedení tohoto mapování ef změní hodnoty cizího klíče podle potřeby, když se změní odkazy mezi objekty a změní odkazy mezi objekty podle potřeby při změně hodnot cizího klíče.

Poznámka:

Primární klíče se používají pro více než mapování relací. Další informace najdete v tématu Klíče .

Například výše uvedené typy entit lze aktualizovat pomocí vlastností primárního a cizího klíče:

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

Tip

Vlastnosti primárního a cizího klíče nemusí být veřejně viditelné vlastnosti typu entity. I když jsou však vlastnosti skryté, je důležité si uvědomit, že v modelu EF stále existují.

Vlastnost primárního Blogklíče , Blog.Ida cizí Postklíč vlastnost , Post.BlogIdpak může být přidružena k odkazům ("navigace") mezi typy entit (Blog.Posts a Post.Blog). Ef to provádí automaticky při vytváření jednoduché relace, jako je tato, ale může být také zadán explicitně při přepsání OnModelCreating metody vašeho DbContext. Příklad:

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

Nyní se všechny tyto vlastnosti budou chovat koherentně společně jako reprezentace jednoho vztahu mezi Blog a Post.

Další informace

EF podporuje mnoho různých typů relací s mnoha různými způsoby, jak lze tyto relace reprezentovat a konfigurovat. Pokud chcete přejít na příklady pro různé druhy relací, přečtěte si téma:

  • Relace 1:N, ve kterých je jedna entita přidružená k libovolnému počtu dalších entit.
  • Relace 1:1, ve kterých je jedna entita přidružená k jiné jedné entitě.
  • Relace M:N, ve kterých je libovolný počet entit přidružených k libovolnému počtu dalších entit.

Pokud s EF teprve začínáte, vyzkoušejte příklady propojené v bodech odrážek výše dobrým způsobem, jak získat pocit, jak vztahy fungují.

Podrobnější informace o vlastnostech typů entit zahrnutých v mapování relací najdete tady:

  • Cizí a hlavní klíče v relacích, které se týkají mapování cizích klíčů na databázi.
  • Navigace relací, které popisují, jak jsou navigace vrstvené přes cizí klíč, aby poskytovaly objektově orientované zobrazení relace.

Modely EF se vytvářejí pomocí kombinace tří mechanismů: konvence, atributy mapování a rozhraní API pro tvůrce modelů. Většina příkladů ukazuje rozhraní API pro vytváření modelů. Další informace o dalších možnostech najdete tady:

  • Konvence relací, které zjišťují typy entit, jejich vlastnosti a vztahy mezi těmito typy.
  • Atributy mapování relací, které je možné použít jako alternativu k rozhraní API pro vytváření modelu pro některé aspekty konfigurace vztahu.

Důležité

Rozhraní API pro vytváření modelů je konečným zdrojem pravdy pro model EF – vždy má přednost před konfigurací zjištěnou konvencí nebo určenými atributy mapování. Je to také jediný mechanismus s plnou věrností ke konfiguraci všech aspektů modelu EF.

Mezi další témata související s relacemi patří:

  • Kaskádové odstranění, které popisují, jak se související entity dají automaticky odstranit, když SaveChanges je volána nebo SaveChangesAsync volána.
  • Typy vlastněných entit používají speciální typ relace "vlastnící", která znamená silnější propojení mezi těmito dvěma typy než "normální" relace, které jsou zde popsány. Mnoho konceptů popsaných zde pro normální relace se přenáší do vlastněných relací. Vlastní relace ale mají také vlastní zvláštní chování.

Tip

Při čtení dokumentace si projděte glosář termínů relací, které vám pomůžou porozumět použité terminologii.

Použití relací

Relace definované v modelu se dají použít různými způsoby. Příklad: