Dela via


Introduktion till relationer

Det här dokumentet ger en enkel introduktion till representationen av relationer i objektmodeller och relationsdatabaser, inklusive hur EF Core mappar mellan de två.

Relationer i objektmodeller

En relation definierar hur två entiteter relaterar till varandra. När du till exempel modellerar inlägg i en blogg är varje inlägg relaterat till den blogg som det publiceras på, och bloggen är relaterad till alla inlägg som publiceras på den bloggen.

I ett objektorienterat språk som C# representeras blogg och inlägg vanligtvis av två klasser: Blog och Post. Till exempel:

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

I klasserna ovan finns det inget som tyder på att Blog och Post är relaterade. Detta kan läggas till i objektmodellen genom att lägga till en referens från Post till den Blog som den publiceras på:

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

På samma sätt kan den motsatta riktningen för samma relation representeras som en samling Post objekt på varje Blog:

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

    public ICollection<Post> Posts { get; }
}

Den här anslutningen från Blog till Post och omvänt från Post tillbaka till Blog kallas för en "relation" i EF Core.

Viktig

En enda förhållande kan vanligtvis traverseras i båda riktningarna. I det här exemplet är det från Blog till Post via egenskapen Blog.Posts och från Post tillbaka till Blog via egenskapen Post.Blog. Det här är en relation, inte två.

Tips

I EF Core kallas egenskaperna Blog.Posts och Post.Blog "navigering".

Relationer i relationsdatabaser

Relationsdatabaser representerar relationer med hjälp av främmande nycklar. Om du till exempel använder SQL Server eller Azure SQL kan följande tabeller användas för att representera våra Post- och Blog klasser:

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

I den här relationsmodellen får tabellerna Posts och Blogs vardera en "primärnyckelkolumn". Värdet för primärnyckeln identifierar unikt varje inlägg eller blogg. Dessutom får Posts-tabellen en "främmande nyckel"-kolumn. Primärnyckelkolumnen BlogsId refereras av den främmande nyckelkolumnen BlogId i tabellen Posts. Den här kolumnen är "begränsad" så att alla värden i kolumnen BlogId i Postsmåste matcha ett värde i kolumnen Id i Blogs. Den här matchning avgör vilken blogg varje inlägg är relaterat till. Om till exempel BlogId värdet på en rad i tabellen Posts är 7 publiceras inlägget som representeras av den raden i bloggen med primärnyckeln 7.

Mappa relationer i EF Core

EF Core-relationsmappning handlar om att mappa den primära nyckel-/sekundärnyckelrepresentationen som används i en relationsdatabas till referenserna mellan objekt som används i en objektmodell.

I den mest grundläggande meningen innebär detta:

  • Lägga till en primärnyckelegenskap till varje entitetstyp.
  • Lägga till en utländsk nyckelegenskap till en entitetstyp.
  • Associera referenserna mellan entitetstyper med de primära och externa nycklarna för att skapa en enda relationskonfiguration.

När den här mappningen har gjorts ändrar EF värdena för sekundärnyckeln efter behov när referenserna mellan objekt ändras och ändrar referenserna mellan objekt efter behov när sekundärnyckelvärdena ändras.

Notera

Primära nycklar används för mer än mappning av relationer. Mer information finns i Nycklar.

Till exempel kan de entitetstyper som visas ovan uppdateras med primär- och sekundärnyckelegenskaper:

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

Tips

Primär- och sekundärnyckelegenskaper behöver inte vara offentligt synliga egenskaper för entitetstypen. Men även när egenskaperna är dolda är det viktigt att känna igen att de fortfarande finns i EF-modellen.

Den primära nyckelegenskapen för Blog, Blog.Idoch egenskapen främmande nyckel för Post, Post.BlogIdkan kopplas ihop med referenserna ("navigeringar") mellan entitetstyperna (Blog.Posts och Post.Blog). Detta görs automatiskt av EF när du skapar en enkel relation som den här, men kan också anges uttryckligen när du åsidosättar OnModelCreating-metoden för din DbContext. Till exempel:

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

Nu fungerar alla dessa egenskaper tillsammans som en representation av en enda relation mellan Blog och Post.

Ta reda på mer

EF stöder många olika typer av relationer, med många olika sätt att representera och konfigurera dessa relationer. För att snabbt komma igång med exempel för olika typer av relationer, se:

Om du är nybörjare på EF är det ett bra sätt att få en känsla för hur relationer fungerar genom att prova exemplen som är länkade i punktpunkterna ovan.

Mer information om egenskaperna för entitetstyper som ingår i relationsmappning finns i:

EF-modeller skapas med hjälp av en kombination av tre mekanismer: konventioner, mappningsattribut och modellverktygets API. De flesta av exemplen visar modellskapande-API:et. Mer information om andra alternativ finns i:

  • Relationskonventioner, som identifierar entitetstyper, deras egenskaper och relationerna mellan typerna.
  • Relationsmappningsattribut, som kan användas som ett alternativ till modellskapande-API:et för vissa aspekter av relationskonfigurationen.

Viktig

Modellskapande-API:et är den slutliga sanningskällan för EF-modellen – den har alltid företräde framför konfigurationen som identifieras av konventionen eller anges av mappningsattribut. Det är också den enda mekanismen med fullständig exakthet för att konfigurera alla delar av EF-modellen.

Andra ämnen som rör relationer är:

  • Cascade tar bort, som beskriver hur relaterade entiteter kan tas bort automatiskt när SaveChanges eller SaveChangesAsync anropas.
  • Ägda entitetstyper använda en särskild typ av "ägande" relation som innebär en starkare anslutning mellan de två typerna än de "normala" relationer som beskrivs här. Många av de begrepp som beskrivs här för normala relationer överförs till ägda relationer. Men ägda relationer har också sina egna speciella beteenden.

Tips

Se ordlista över relationstermer efter behov när du läser dokumentationen för att förstå den terminologi som används.

Använda relationer

Relationer som definieras i modellen kan användas på olika sätt. Till exempel: