Inleiding tot relaties
Dit document biedt een eenvoudige inleiding tot hoe relaties in objectmodellen en relationele databases worden weergegeven, inclusief hoe EF Core tussen beide mapt.
Relaties in objectmodellen
Een relatie definieert hoe twee entiteiten zich met elkaar verhouden. Wanneer u bijvoorbeeld berichten in een blog modelleert, is elk bericht gerelateerd aan de blog waarop het is gepubliceerd en is het blog gerelateerd aan alle berichten die op die blog zijn gepubliceerd.
In een objectgeoriënteerde taal zoals C# worden de blog en post meestal vertegenwoordigd door twee klassen: Blog
en Post
. Bijvoorbeeld:
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; }
}
In de bovenstaande klassen is er niets om aan te geven dat Blog
en Post
gerelateerd zijn. Dit kan worden toegevoegd aan het objectmodel door een verwijzing van Post
toe te voegen aan de Blog
waarop het wordt gepubliceerd:
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; }
}
Op dezelfde manier kan de tegenovergestelde richting van dezelfde relatie worden weergegeven als een verzameling Post
objecten op elk Blog
:
public class Blog
{
public string Name { get; set; }
public virtual Uri SiteUri { get; set; }
public ICollection<Post> Posts { get; }
}
Deze verbinding van Blog
met Post
en, omgekeerd, van Post
terug naar Blog
wordt een 'relatie' genoemd in EF Core.
Belangrijk
Een enkele-relatie kan doorgaans in beide richtingen worden doorkruist. In dit voorbeeld is dat van Blog
naar Post
via de eigenschap Blog.Posts
en van Post
terug naar Blog
via de eigenschap Post.Blog
. Dit is één relatie, niet twee.
Tip
In EF Core worden de eigenschappen Blog.Posts
en Post.Blog
'navigatie' genoemd.
Relaties in relationele databases
Relationele databases vertegenwoordigen relaties met behulp van vreemde sleutels. Als u bijvoorbeeld SQL Server of Azure SQL gebruikt, kunnen de volgende tabellen worden gebruikt om de klassen Post
en Blog
weer te geven:
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]));
In dit relationele model krijgen de tabellen Posts
en Blogs
elk een kolom met de primaire sleutel. De waarde van de primaire sleutel identificeert elk bericht of blog uniek. Bovendien krijgt de Posts
tabel een kolom met een "foreign key". De Blogs
primaire-sleutelkolom Id
wordt verwezen naar door de BlogId
vreemde-sleutelkolom van de Posts
tabel. Deze kolom is 'beperkt', zodat elke waarde in de kolom BlogId
van Posts
moet overeenkomen met een waarde in de Id
kolom van Blogs
. Deze overeenkomst bepaalt aan welke blog elk bericht is gerelateerd. Als de BlogId
waarde in één rij van de tabel Posts
bijvoorbeeld 7 is, wordt het bericht dat wordt vertegenwoordigd door die rij, gepubliceerd in het blog met de primaire sleutel 7.
Relaties in kaart brengen in EF Core
EF Core-relatietoewijzing draait om het toewijzen van de primaire sleutel/vreemde sleutelweergave die in een relationele database wordt gebruikt aan de verwijzingen tussen objecten die in een objectmodel worden gebruikt.
In de meest elementaire zin omvat dit:
- Een primaire-sleuteleigenschap toevoegen aan elk entiteitstype.
- Een vreemde-sleuteleigenschap toevoegen aan één entiteitstype.
- De verwijzingen tussen entiteitstypen koppelen aan de primaire en buitenlandse sleutels om een enkele relatieconfiguratie te vormen.
Zodra deze toewijzing is aangebracht, wijzigt EF de buitenlandse sleutelwaarden zo nodig wanneer de verwijzingen tussen objecten veranderen en wijzigt het de verwijzingen tussen objecten zo nodig wanneer de buitenlandse sleutelwaarden veranderen.
Notitie
Primaire sleutels worden gebruikt voor meer dan het vastleggen van relaties. Zie Sleutels voor meer informatie.
De hierboven weergegeven entiteitstypen kunnen bijvoorbeeld worden bijgewerkt met primaire en vreemde sleuteleigenschappen.
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; }
}
Fooi
Eigenschappen van primaire en refererende sleutels hoeven niet openbaar zichtbare eigenschappen van het entiteitstype te zijn. Zelfs wanneer de eigenschappen zijn verborgen, is het echter belangrijk te herkennen dat ze nog steeds bestaan in het EF-model.
De primaire sleuteleigenschap van Blog
, Blog.Id
en de refererende sleuteleigenschap van Post
, Post.BlogId
, kunnen vervolgens worden gekoppeld aan de verwijzingen ('navigatie') tussen de entiteitstypen (Blog.Posts
en Post.Blog
). Dit wordt automatisch gedaan door EF bij het bouwen van een eenvoudige relatie zoals deze, maar kan ook expliciet worden opgegeven bij het overschrijven van de OnModelCreating
methode van uw DbContext
. Bijvoorbeeld:
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 gedragen al deze eigenschappen zich coherent samen als een representatie van één relatie tussen Blog
en Post
.
Meer informatie
EF ondersteunt veel verschillende typen relaties, met veel verschillende manieren waarop deze relaties kunnen worden weergegeven en geconfigureerd. Als u voorbeelden voor verschillende soorten relaties wilt bekijken, raadpleegt u:
- een-op-veel-relaties, waarin één entiteit is gekoppeld aan een willekeurig aantal andere entiteiten.
- een-op-een-relaties, waarin één entiteit is gekoppeld aan een andere entiteit.
- veel-op-veel-relaties, waarin een willekeurig aantal entiteiten is gekoppeld aan een willekeurig aantal andere entiteiten.
Als u niet bekend bent met EF, kunt u de voorbeelden in de bovenstaande opsommingstekens gebruiken om een goed idee te krijgen van de werking van relaties.
Als u meer wilt weten over de eigenschappen van entiteitstypen die betrokken zijn bij het toewijzen van relaties, raadpleegt u:
- Vreemde en primaire sleutels in relaties, waarin wordt behandeld hoe vreemde sleutels aan de database worden toegewezen.
- Relatienavigaties, waarin wordt beschreven hoe navigaties over een vreemde sleutel worden gelaagd om een objectgeoriënteerde weergave van de relatie te bieden.
EF-modellen worden gebouwd met behulp van een combinatie van drie mechanismen: conventies, toewijzingskenmerken en de API van de modelbouwer. In de meeste voorbeelden ziet u de API voor het bouwen van modellen. Zie voor meer informatie over andere opties:
- relatieconventies, waarmee entiteitstypen, hun eigenschappen en de relaties tussen de typen worden gedetecteerd.
- kenmerken voor relatietoewijzing, die kunnen worden gebruikt als alternatief voor de api voor het bouwen van modellen voor bepaalde aspecten van de relatieconfiguratie.
Belangrijk
De API voor het bouwen van modellen is de uiteindelijke bron van waarheid voor het EF-model. Het heeft altijd voorrang op configuratie die is gedetecteerd volgens conventie of opgegeven door toewijzingskenmerken. Het is ook het enige mechanisme met volledige betrouwbaarheid om elk aspect van het EF-model te configureren.
Andere onderwerpen met betrekking tot relaties zijn:
-
trapgewijsverwijderen, waarin wordt beschreven hoe gerelateerde entiteiten automatisch kunnen worden verwijderd wanneer
SaveChanges
ofSaveChangesAsync
wordt aangeroepen. - entiteitstypen in eigendom een speciale type 'eigendomsrelatie' gebruiken die een sterkere verbinding tussen de twee typen impliceert dan de 'normale' relaties die hier worden besproken. Veel van de concepten die hier worden beschreven voor normale relaties worden overgedragen naar relaties die eigendom zijn. Relaties in eigendom hebben echter ook hun eigen speciale gedrag.
Tip
Raadpleeg de woordenlijst van relatietermen indien nodig bij het lezen van de documentatie om inzicht te verkrijgen in de gebruikte terminologie.
Relaties gebruiken
Relaties die in het model zijn gedefinieerd, kunnen op verschillende manieren worden gebruikt. Bijvoorbeeld:
- Relaties kunnen op drie manieren worden gebruikt om gerelateerde gegevens op te vragen:
- Relaties kunnen worden gebruikt in gegevenszaaien door het koppelen van PK-waarden aan FK-waarden.
- Relaties kunnen worden gebruikt om grafieken van entiteitente
. Relaties worden vervolgens door de wijzigingstracker gebruikt voor: - Wijzigingen in relaties detecteren en herstel uitvoeren
-
externe sleutelupdates verzenden naar de database met
SaveChanges
ofSaveChangesAsync