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, co by naznačovalo, že Blog a Post jsou propojené. Toto lze přidat do objektového modelu přidáním odkazu z Post na Blog, na který je to publikováno.

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 do Post a zpětné připojení v opačném směru z Post do Blog se v EF Core označuje jako "vztah".

Důležité

Jednosměrnou relaci lze obvykle projít oběma směry. V tomto příkladu je to z vlastnosti Blog.Posts od Blog do Post a zpět z vlastnosti Post.Blog od Post do Blog. Toto je jedna relace, ne dvě.

Tip

V EF Core se vlastnosti Blog.Posts a Post.Blog nazývají "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 má každá z tabulek Posts a Blogs svůj vlastní sloupec s označením "primární klíč". Hodnota primárního klíče jednoznačně identifikuje každý příspěvek nebo blog. Kromě toho má tabulka Posts sloupec „foreign key“. Sloupec primárního Id klíče Blogs je referenčním sloupcem cizího klíče BlogId v tabulce Posts. Tento sloupec je "omezený", aby jakákoli hodnota ve BlogId sloupci Postsmusí odpovídat hodnotě Id ve sloupci Blogs. Tato shoda určuje, ke kterému blogu 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 klíče Blog, Blog.Id a vlastnost cizího klíče Post, Post.BlogId pak 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 v tomto případě, ale může být také nastaven 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 spojena s jakýmkoli počtem jiných entit.
  • Relace 1:1, ve kterých je jedna entita přidružená k jiné jedné entitě.
  • Relace M:N, při kterých může být libovolný počet entit spojen s libovolným počtem jiných entit.

Pokud jste v EF nováčkem, je vyzkoušení příkladů odkazovaných v bodech výše dobrým způsobem, jak se seznámit s tím, jak vztahy fungují.

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

  • Cizí a primární klíče v relacích, které popisují 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é popisuje, jak se související entity dají automaticky odstranit, když je voláno SaveChanges nebo SaveChangesAsync.
  • 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í svá vlastní zvláštní chování.

Tip

Při čtení dokumentace si projděte glosář vztahových termínů pro lepší pochopení používané terminologie.

Použití relací

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