Megosztás:


Modell létrehozása és konfigurálása

Az EF Core egy metaadat-modellt használ annak leírására, hogy az alkalmazás entitástípusai hogyan vannak leképezve az alapul szolgáló adatbázisra. Ez a modell konvenciók – heurisztikusok használatával készült, amelyek gyakran használt mintákat keresnek. A modell ezután testre szabható leképezési attribútumok (más néven adatjegyzetek) és/vagy a metódusok (más néven ModelBuilder)meghívásávalOnModelCreating, amelyek mindkét esetben felülírják a konvenciók által végrehajtott konfigurációt.

A legtöbb konfiguráció bármilyen adattárat megcélzó modellre alkalmazható. A szolgáltatók engedélyezhetik az adott adattárra jellemző konfigurációt, és figyelmen kívül hagyhatják a nem támogatott vagy nem alkalmazható konfigurációt is. A szolgáltatóspecifikus konfiguráció dokumentációját az Adatbázis-szolgáltatók szakaszban találja.

Jótanács

A cikk mintáit a GitHubon tekintheti meg.

A fluent API használata modell konfigurálásához

Felülbírálhatja a metódust a OnModelCreating származtatott kontextusban, és a Fluent API-val konfigurálhatja a modellt. Ez a leghatékonyabb konfigurációs módszer, és lehetővé teszi a konfiguráció megadását az entitásosztályok módosítása nélkül. A Fluent API-konfiguráció a legmagasabb prioritást élvezi, és felülírja a konvenciók és az adatjegyzetek használatát. A rendszer a konfigurációt a metódusok meghívásának sorrendjében alkalmazza, és ütközések esetén a legutóbbi hívás felülírja a korábban megadott konfigurációt.

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

Jótanács

Ha ugyanazt a konfigurációt több objektumra szeretné alkalmazni a modellben, tekintse meg a tömeges konfigurációt.

Csoportosítási konfiguráció

A metódus méretének OnModelCreating csökkentése érdekében egy entitástípus összes konfigurációja kinyerhető egy külön implementálási IEntityTypeConfiguration<TEntity>osztályba.

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

Ezután egyszerűen hívja meg a Configure metódust a OnModelCreating-ból.

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

Az összes konfiguráció alkalmazása egy szerelvényben

Az adott assemblyben a IEntityTypeConfiguration implementáló típusokban megadott összes konfiguráció alkalmazható.

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

Megjegyzés:

A konfigurációk alkalmazásának sorrendje nincs meghatározva, ezért ez a módszer csak akkor használható, ha a sorrend nem számít.

Entitástípusok használata EntityTypeConfigurationAttribute

Ahelyett, hogy explicit módon hívna Configure, egy EntityTypeConfigurationAttribute olyan entitástípusra helyezhető el, amely alapján az EF Core megtalálja és használhatja a megfelelő konfigurációt. Például:

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

Ez az attribútum azt jelenti, hogy az EF Core a megadott IEntityTypeConfiguration implementációt fogja használni, amikor az Book entitástípus szerepel a modellben. Az entitástípus egy modellben szerepel a szokásos mechanizmusok egyikével. Például az entitástípushoz DbSet<TEntity> tartozó tulajdonság létrehozásával:

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

    //...

Vagy regisztrálja a következő helyen OnModelCreating:

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

Megjegyzés:

EntityTypeConfigurationAttribute típusok nem lesznek automatikusan felderítve egy szerelvényben. Az entitástípusokat hozzá kell adni a modellhez, mielőtt az attribútumot felderítené az adott entitástípuson.

Modell konfigurálása adatjegyzetekkel

Az osztályokra és tulajdonságokra bizonyos attribútumokat (más néven adatjegyzeteket) is alkalmazhat. Az adatannotációk felülírják a konvenciókat, de a Fluent API-konfiguráció felülírja őket.

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

Beépített konvenciók

Az EF Core számos olyan modellépítési konvenciót tartalmaz, amelyek alapértelmezés szerint engedélyezve vannak. Ezek mindegyike megtalálható az interfészt megvalósító IConvention osztályok listájában. Ez a lista azonban nem tartalmazza a külső adatbázis-szolgáltatók és beépülő modulok által bevezetett konvenciókat.

Az alkalmazások eltávolíthatják vagy lecserélhetik ezen konvenciók bármelyikét, valamint új egyéni konvenciókat adhatnak hozzá, amelyek az EF által nem felismert minták konfigurációját alkalmazzák.

Jótanács

Az alábbi kód ModelBuildingConventionsSample.cs származik.

Meglévő konvenció eltávolítása

Előfordulhat, hogy az egyik beépített konvenció nem felel meg az alkalmazásnak, ami esetben eltávolítható.

Jótanács

Ha a modell nem használ leképezési attribútumokat (más néven adatjegyzeteket) a konfigurációhoz, akkor a névvel végződő AttributeConvention összes konvenciót biztonságosan eltávolíthatja a modellépítés felgyorsítása érdekében.

Példa: Ne hozzon létre indexeket idegen kulcsoszlopokhoz

Általában érdemes indexeket létrehozni az idegen kulcsú (FK) oszlopokhoz, ezért van erre egy beépített konvenció: ForeignKeyIndexConvention. Ha megnézzük a modell hibakeresési nézetét egy Post entitástípus esetén, amelynek kapcsolatai vannak Blog-vel és Author-vel, láthatjuk, hogy két index jön létre – az egyik az BlogId FK-hoz, a másik az AuthorId FK-hoz.

  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

Az indexek azonban többletterheléssel rendelkeznek, és előfordulhat, hogy nem mindig célszerű az összes FK-oszlophoz létrehozni őket. Ennek érdekében a ForeignKeyIndexConvention eltávolítható a modell létrehozásakor.

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

A modell hibakeresési nézetét tekintve egyelőre Post azt látjuk, hogy az FK-k indexei nem lettek létrehozva:

  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

Amikor kívánatos, az indexek továbbra is explicit módon hozhatók létre az idegen kulcsoszlopokhoz, akár a IndexAttribute használatával, akár a OnModelCreating konfigurációjával.

Hibakeresési nézet

A modellszerkesztő hibakeresési nézete az IDE hibakeresőjében érhető el. Például a Visual Studióval:

A Modellszerkesztő hibakeresési nézetének elérése a Visual Studio hibakeresőjével

Közvetlenül a kódból is elérhető, például a hibakeresési nézet elküldéséhez a konzolra:

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

A hibakeresési nézet rövid és hosszú formátumú. A hosszú űrlap tartalmazza az összes széljegyzetet is, ami akkor lehet hasznos, ha relációs vagy szolgáltatóspecifikus metaadatokat kell megtekintenie. A hosszú nézet kódból is elérhető:

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