Dela via


Skapa och konfigurera en modell

EF Core använder en metadatamodell för att beskriva hur programmets entitetstyper mappas till den underliggande databasen. Den här modellen är byggd med hjälp av en uppsättning konventioner – heuristik som letar efter vanliga mönster. Modellen kan sedan anpassas med hjälp av mappningsattribut (även kallade dataanteckningar) och/eller anrop till ModelBuilder metoderna (även kallat fluent API) i OnModelCreating, som båda åsidosätter konfigurationen som utförs av konventioner.

De flesta konfigurationer kan tillämpas på en modell som riktar sig till alla datalager. Leverantörer kan också aktivera konfiguration som är specifik för ett visst datalager och de kan också ignorera konfiguration som inte stöds eller inte är tillämplig. Dokumentation om providerspecifik konfiguration finns i avsnittet Databasprovidrar .

Tips/Råd

Du kan visa den här artikelns exempel på GitHub.

Använda fluent API för att konfigurera en modell

Du kan åsidosätta OnModelCreating metoden i din härledda kontext och använda API:et fluent för att konfigurera din modell. Det här är den mest kraftfulla konfigurationsmetoden och gör att konfiguration kan anges utan att ändra entitetsklasserna. Fluent API-konfigurationen har högsta prioritet och åsidosätter konventioner och dataanteckningar. Konfigurationen tillämpas i den ordning metoderna anropas och om det finns konflikter åsidosätter det senaste anropet tidigare angiven konfiguration.

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

Tips/Råd

Om du vill tillämpa samma konfiguration på flera objekt i modellen kan du läsa masskonfiguration.

Grupperingskonfiguration

Om du vill minska storleken på OnModelCreating metoden kan all konfiguration för en entitetstyp extraheras till en separat klass som implementerar IEntityTypeConfiguration<TEntity>.

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

Anropa sedan bara Configure -metoden från OnModelCreating.

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

Tillämpa alla konfigurationer i en sammansättning

Det är möjligt att tillämpa alla konfigurationer som anges i typer som implementerar IEntityTypeConfiguration i en viss sammansättning.

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

Anmärkning

Ordningen i vilken konfigurationerna ska tillämpas är odefinierad, därför bör den här metoden endast användas när ordningen inte spelar någon roll.

Använda EntityTypeConfigurationAttribute på entitetstyper

I stället för att uttryckligen anropa Configurekan en EntityTypeConfigurationAttribute i stället placeras på entitetstypen så att EF Core kan hitta och använda lämplig konfiguration. Till exempel:

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

Det här attributet innebär att EF Core använder den angivna IEntityTypeConfiguration implementeringen när entitetstypen Book ingår i en modell. Entitetstypen ingår i en modell med någon av de normala mekanismerna. Till exempel genom att skapa en DbSet<TEntity> egenskap för entitetstypen:

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

    //...

Eller genom att registrera den i OnModelCreating:

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

Anmärkning

EntityTypeConfigurationAttribute typer upptäcks inte automatiskt i en assembly. Entitetstyper måste läggas till i modellen innan attributet identifieras för den entitetstypen.

Använda dataanteckningar för att konfigurera en modell

Du kan också använda vissa attribut (kallas dataanteckningar) för dina klasser och egenskaper. Dataanteckningar åsidosätter konventioner, men åsidosätts av Fluent API-konfiguration.

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

Inbyggda konventioner

EF Core innehåller många modellbyggkonventioner som är aktiverade som standard. Du hittar alla i listan över klasser som implementerar IConvention gränssnittet. Den listan innehåller dock inte konventioner som införts av tredjepartsdatabasleverantörer och plugin-program.

Program kan ta bort eller ersätta någon av dessa konventioner, samt lägga till nya anpassade konventioner som tillämpar konfiguration för mönster som inte känns igen av EF direkt.

Tips/Råd

Koden som visas nedan kommer från ModelBuildingConventionsSample.cs.

Ta bort en befintlig konvention

Ibland är en av de inbyggda konventionerna kanske inte lämpliga för ditt program, i vilket fall det kan tas bort.

Tips/Råd

Om din modell inte använder mappningsattribut (även kallade dataanteckningar) för konfiguration kan alla konventioner med namnet som slutar i AttributeConvention tas bort på ett säkert sätt för att påskynda modellskapandet.

Exempel: Skapa inte index för kolumner för främmande nycklar

Det är vanligtvis klokt att skapa index för FK-kolumner (sekundärnyckel) och därför finns det en inbyggd konvention för detta: ForeignKeyIndexConvention. Om du tittar på modellfelsökningsvyn för en entitetstyp Post med relationer till Blog och Authorkan vi se att två index har skapats – ett för BlogId FK och det andra för 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

Index har dock omkostnader och det kanske inte alltid är lämpligt att skapa dem för alla FK-kolumner. För att uppnå detta ForeignKeyIndexConvention kan du ta bort när du skapar modellen:

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

Om vi tittar på felsökningsvyn för modellen för Post nu, ser vi att indexen på FK:er inte har skapats.

  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

När så önskas kan index fortfarande skapas uttryckligen för utländska nyckelkolumner, antingen med användningen av IndexAttribute eller med konfigurationen i OnModelCreating.

Felsökningsvy

Felsökningsvyn för modellbyggaren kan nås i felsökningsprogrammet för din IDE. Till exempel med Visual Studio:

Komma åt felsökningsvyn för modellverktyget från Visual Studio-felsökningsprogrammet

Den kan också nås direkt från kod, till exempel för att skicka felsökningsvyn till konsolen:

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

Felsökningsvyn har ett kort formulär och ett långt formulär. Det långa formuläret innehåller även alla anteckningar, vilket kan vara användbart om du behöver visa relations- eller providerspecifika metadata. Den långa vyn kan också nås från kod:

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