Share via


Een model maken en configureren

EF Core maakt gebruik van een metagegevensmodel om te beschrijven hoe de entiteitstypen van de toepassing worden toegewezen aan de onderliggende database. Dit model wordt gebouwd met behulp van een set conventies : heuristieken die zoeken naar veelvoorkomende patronen. Het model kan vervolgens worden aangepast met behulp van toewijzingskenmerken (ook wel gegevensaantekeningen genoemd) en/of aanroepen naar de ModelBuilder methoden (ook wel fluent API genoemd) in OnModelCreating, waarbij beide de configuratie, uitgevoerd door conventies, overschrijven.

De meeste configuratie kan worden toegepast op een model dat is gericht op elk gegevensarchief. Providers kunnen ook configuratie inschakelen die specifiek is voor een bepaald gegevensarchief en ze kunnen ook configuratie negeren die niet wordt ondersteund of niet van toepassing is. Zie de sectie Databaseproviders voor documentatie over providerspecifieke configuratie.

Aanbeveling

U kunt de voorbeelden van dit artikel bekijken op GitHub.

Fluent API gebruiken om een model te configureren

U kunt de OnModelCreating methode in uw afgeleide context overschrijven en de fluent-API gebruiken om uw model te configureren. Dit is de krachtigste configuratiemethode en maakt het mogelijk om de configuratie op te geven zonder uw entiteitsklassen te wijzigen. Fluent API-configuratie heeft de hoogste prioriteit en overschrijft conventies en gegevensaantekeningen. De configuratie wordt toegepast in de volgorde waarin de methoden worden aangeroepen en als er conflicten zijn met de meest recente aanroep, wordt de eerder opgegeven configuratie overschreven.

using Microsoft.EntityFrameworkCore;

namespace EFModeling.EntityProperties.FluentAPI.Required;

internal class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }

    #region Required
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>()
            .Property(b => b.Url)
            .IsRequired();
    }
    #endregion
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
}

Aanbeveling

Als u dezelfde configuratie wilt toepassen op meerdere objecten in het model, raadpleegt u bulkconfiguratie.

Groeperingsconfiguratie

Als u de grootte van de OnModelCreating methode wilt verkleinen, kan alle configuratie voor een entiteitstype worden geëxtraheerd naar een afzonderlijke klasse die wordt geïmplementeerd IEntityTypeConfiguration<TEntity>.

public class BlogEntityTypeConfiguration : IEntityTypeConfiguration<Blog>
{
    public void Configure(EntityTypeBuilder<Blog> builder)
    {
        builder
            .Property(b => b.Url)
            .IsRequired();
    }
}

Roep vervolgens de Configure methode aan vanuit OnModelCreating.

new BlogEntityTypeConfiguration().Configure(modelBuilder.Entity<Blog>());

Alle configuraties in een assembly toepassen

Het is mogelijk om alle configuraties toe te passen die zijn opgegeven in typen die in een bepaalde assembly worden geïmplementeerd IEntityTypeConfiguration .

modelBuilder.ApplyConfigurationsFromAssembly(typeof(BlogEntityTypeConfiguration).Assembly);

Opmerking

De volgorde waarin de configuraties worden toegepast, is niet gedefinieerd. Deze methode mag daarom alleen worden gebruikt wanneer de volgorde niet van belang is.

Gebruiken EntityTypeConfigurationAttribute op entiteitstypen

In plaats van expliciet aan te roepen Configure, kan een EntityTypeConfigurationAttribute in plaats daarvan worden geplaatst op het entiteitstype, zodat EF Core de juiste configuratie kan vinden en gebruiken. Voorbeeld:

[EntityTypeConfiguration(typeof(BookConfiguration))]
public class Book
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Isbn { get; set; }
}

Dit kenmerk betekent dat EF Core de opgegeven IEntityTypeConfiguration implementatie gebruikt wanneer het Book entiteitstype wordt opgenomen in een model. Het entiteitstype is opgenomen in een model met behulp van een van de normale mechanismen. Bijvoorbeeld door een DbSet<TEntity> eigenschap te maken voor het entiteitstype:

public class BooksContext : DbContext
{
    public DbSet<Book> Books { get; set; }

    //...

Of door het te registreren in OnModelCreating:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Book>();
}

Opmerking

EntityTypeConfigurationAttribute typen worden niet automatisch ontdekt in een assembly. Entiteitstypen moeten worden toegevoegd aan het model voordat het kenmerk wordt gedetecteerd op dat entiteitstype.

Gegevensaantekeningen gebruiken om een model te configureren

U kunt ook bepaalde kenmerken (ook wel gegevensaantekeningen genoemd) toepassen op uw klassen en eigenschappen. Gegevensaantekeningen overschrijven conventies, maar worden overschreven door de Fluent API-configuratie.

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;

namespace EFModeling.EntityProperties.DataAnnotations.Annotations;

internal class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
}

[Table("Blogs")]
public class Blog
{
    public int BlogId { get; set; }

    [Required]
    public string Url { get; set; }
}

Ingebouwde conventies

EF Core bevat veel modelbouwconventies die standaard zijn ingeschakeld. U vindt ze allemaal in de lijst met klassen die de IConvention interface implementeren. Deze lijst bevat echter geen conventies die zijn geïntroduceerd door databaseproviders en invoegtoepassingen van derden.

Toepassingen kunnen een van deze conventies verwijderen of vervangen, en nieuwe aangepaste conventies toevoegen die configuratie toepassen op patronen die niet worden herkend door EF.

Aanbeveling

De onderstaande code is afkomstig van ModelBuildingConventionsSample.cs.

Een bestaande conventie verwijderen

Soms is een van de ingebouwde conventies mogelijk niet geschikt voor uw toepassing, in welk geval het kan worden verwijderd.

Aanbeveling

Als uw model geen toewijzingskenmerken (ook wel gegevensaantekeningen genoemd) gebruikt voor de configuratie, kunnen alle conventies met de naam die eindigen AttributeConvention veilig worden verwijderd om het bouwen van modellen te versnellen.

Voorbeeld: Geen indexen maken voor kolommen met vreemde sleutels

Het is meestal zinvol om indexen te maken voor FK-kolommen (vreemde sleutel), daarom is er een ingebouwde standaard voor: ForeignKeyIndexConvention. Bij het bekijken van de foutopsporingsweergave van het model voor een Post entiteitstype met relaties aan Blog en Author, zien we dat er twee indexen worden gemaakt: één voor de BlogId FK en de andere voor de AuthorId FK.

  EntityType: Post
    Properties:
      Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd
      AuthorId (no field, int?) Shadow FK Index
      BlogId (no field, int) Shadow Required FK Index
    Navigations:
      Author (Author) ToPrincipal Author Inverse: Posts
      Blog (Blog) ToPrincipal Blog Inverse: Posts
    Keys:
      Id PK
    Foreign keys:
      Post {'AuthorId'} -> Author {'Id'} ToDependent: Posts ToPrincipal: Author ClientSetNull
      Post {'BlogId'} -> Blog {'Id'} ToDependent: Posts ToPrincipal: Blog Cascade
    Indexes:
      AuthorId
      BlogId

Indexen hebben echter overhead en het is mogelijk niet altijd geschikt om ze te maken voor alle FK-kolommen. Om dit te bereiken, kan het ForeignKeyIndexConvention worden verwijderd bij het bouwen van het model:

protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
    configurationBuilder.Conventions.Remove(typeof(ForeignKeyIndexConvention));
}

Nu we de foutopsporingsweergave van het model Post bekijken, zien we dat de indexen op FK's niet zijn gemaakt:

  EntityType: Post
    Properties:
      Id (int) Required PK AfterSave:Throw ValueGenerated.OnAdd
      AuthorId (no field, int?) Shadow FK
      BlogId (no field, int) Shadow Required FK
    Navigations:
      Author (Author) ToPrincipal Author Inverse: Posts
      Blog (Blog) ToPrincipal Blog Inverse: Posts
    Keys:
      Id PK
    Foreign keys:
      Post {'AuthorId'} -> Author {'Id'} ToDependent: Posts ToPrincipal: Author ClientSetNull
      Post {'BlogId'} -> Blog {'Id'} ToDependent: Posts ToPrincipal: Blog Cascade

Indien gewenst kunnen indexen nog steeds expliciet worden aangemaakt voor kolommen voor vreemde sleutels, hetzij met behulp van de IndexAttribute of met configuratie in OnModelCreating.

Foutopsporingsweergave

De foutopsporingsweergave van de modelbouwer kan worden geopend in het foutopsporingsprogramma van uw IDE. Bijvoorbeeld met Visual Studio:

Toegang tot de foutopsporingsweergave van de opbouwfunctie voor modellen vanuit het foutopsporingsprogramma van Visual Studio

Deze kan ook rechtstreeks vanuit code worden geopend, bijvoorbeeld om de foutopsporingsweergave naar de console te verzenden:

Console.WriteLine(context.Model.ToDebugString());

De foutopsporingsweergave heeft een kort formulier en een lang formulier. Het lange formulier bevat ook alle aantekeningen, wat handig kan zijn als u relationele of providerspecifieke metagegevens wilt weergeven. De lange weergave kan ook worden geopend vanuit code:

Console.WriteLine(context.Model.ToDebugString(MetadataDebugStringOptions.LongDefault));