Vytvoření a konfigurace modelu
EF Core používá model metadat k popisu mapování typů entit aplikace na podkladovou databázi. Tento model je sestaven pomocí sady konvencí – heuristiky, které hledají běžné vzory. Model je pak možné přizpůsobit pomocí atributů mapování (označovaných také jako datové poznámky) a/nebo volání ModelBuilder metod (označovaných také jako fluent API) v OnModelCreatingobou případech přepíše konfiguraci prováděnou konvencí.
Většinu konfigurace je možné použít u modelu, který cílí na jakékoli úložiště dat. Zprostředkovatelé mohou také povolit konfiguraci specifickou pro konkrétní úložiště dat a mohou také ignorovat konfiguraci, která není podporována nebo není použitelná. Dokumentaci ke konfiguraci specifické pro zprostředkovatele najdete v části Poskytovatelé databáze.
Tip
Ukázky tohoto článku můžete zobrazit na GitHubu.
Konfigurace modelu pomocí rozhraní Fluent API
Metodu OnModelCreating
v odvozeném kontextu můžete přepsat a pomocí rozhraní API fluent nakonfigurovat model. Jedná se o nejúčinnější metodu konfigurace, která umožňuje určit konfiguraci beze změny tříd entit. Konfigurace rozhraní Fluent API má nejvyšší prioritu a přepíše konvence a datové poznámky. Konfigurace se použije v pořadí, v jakém se metody volají, a pokud dojde ke konfliktům, poslední volání přepíše dříve zadanou konfiguraci.
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; }
}
Tip
Pokud chcete stejnou konfiguraci použít u více objektů v modelu, podívejte se na hromadnou konfiguraci.
Konfigurace seskupení
Pokud chcete zmenšit velikost metody OnModelCreating
, lze všechny konfigurace nějakého typu entity extrahovat do samostatné třídy implementující IEntityTypeConfiguration<TEntity>.
public class BlogEntityTypeConfiguration : IEntityTypeConfiguration<Blog>
{
public void Configure(EntityTypeBuilder<Blog> builder)
{
builder
.Property(b => b.Url)
.IsRequired();
}
}
Pak stačí vyvolat metodu Configure
z OnModelCreating
.
new BlogEntityTypeConfiguration().Configure(modelBuilder.Entity<Blog>());
Použití všech konfigurací v sestavení
V daném sestavení lze použít veškerou konfiguraci určenou v typech implementujících IEntityTypeConfiguration
.
modelBuilder.ApplyConfigurationsFromAssembly(typeof(BlogEntityTypeConfiguration).Assembly);
Poznámka
Pořadí, v jakém budou konfigurace použity, není definováno, proto by se tato metoda měla použít jen v případě, kdy nezáleží na pořadí.
Použití EntityTypeConfigurationAttribute
u typů entit
Místo explicitního volání Configure
EntityTypeConfigurationAttribute lze místo toho umístit na typ entity tak, aby EF Core mohl najít a použít odpovídající konfiguraci. Příklad:
[EntityTypeConfiguration(typeof(BookConfiguration))]
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
public string Isbn { get; set; }
}
Tento atribut znamená, že EF Core použije zadanou IEntityTypeConfiguration
implementaci při každém Book
zahrnutí typu entity do modelu. Typ entity je součástí modelu pomocí jednoho z normálních mechanismů. Například vytvořením DbSet<TEntity> vlastnosti pro typ entity:
public class BooksContext : DbContext
{
public DbSet<Book> Books { get; set; }
//...
Nebo ho zaregistrujete v OnModelCreating:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Book>();
}
Poznámka
EntityTypeConfigurationAttribute
typy nebudou automaticky zjištěny v sestavení. Typy entit musí být přidány do modelu před zjištěním atributu u tohoto typu entity.
Konfigurace modelu pomocí datových poznámek
U tříd a vlastností můžete také použít určité atributy (označované jako datové poznámky). Datové poznámky přepíší konvence, budou ale přepsány konfigurací rozhraní Fluent API.
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; }
}
Integrované konvence
EF Core obsahuje mnoho konvencí vytváření modelů, které jsou ve výchozím nastavení povolené. Všechny z nich najdete v seznamu tříd, které implementují IConvention rozhraní. Tento seznam ale neobsahuje konvence zavedené poskytovateli databází a moduly plug-in třetích stran.
Aplikace můžou některou z těchto konvencí odebrat nebo nahradit, a také přidat nové vlastní konvence, které použijí konfiguraci pro vzory , které EF nerozpozná.
Tip
Níže uvedený kód pochází z ModelBuildingConventionsSample.cs.
Odebrání existující konvence
Někdy některá z předdefinovaných konvencí nemusí být vhodná pro vaši aplikaci, v takovém případě je možné ji odebrat.
Tip
Pokud váš model pro konfiguraci nepoužívá atributy mapování (neboli datové poznámky), všechny konvence s názvem končícím názvem AttributeConvention
je možné bezpečně odebrat, aby se urychlila sestavování modelu.
Příklad: Nevytvávejte indexy pro sloupce cizího klíče
Obvykle dává smysl vytvářet indexy pro sloupce cizího klíče (FK), a proto existuje předdefinovaná konvence pro toto: ForeignKeyIndexConvention. Při pohledu na zobrazení ladění modelu pro Post
typ entity s relacemi Blog
a Author
vidíme, že dva indexy jsou vytvořené – jeden pro FK a druhý pro BlogId
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
Indexy ale mají režijní náklady a nemusí být vždy vhodné je vytvořit pro všechny sloupce FK. Abyste toho dosáhli, ForeignKeyIndexConvention
můžete ho při sestavování modelu odebrat:
protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
configurationBuilder.Conventions.Remove(typeof(ForeignKeyIndexConvention));
}
Když se teď podíváme na zobrazení ladění modelu Post
, vidíme, že se nevytvořily indexy ve FK:
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
V případě potřeby lze indexy i nadále explicitně vytvářet pro sloupce cizího klíče, a to buď pomocí IndexAttribute konfigurace v OnModelCreating
.
Zobrazení ladění
Zobrazení ladění tvůrce modelů je možné získat v ladicím programu integrovaného vývojového prostředí (IDE). Například se sadou Visual Studio:
Můžete k němu přistupovat také přímo z kódu, například k odeslání zobrazení ladění do konzoly:
Console.WriteLine(context.Model.ToDebugString());
Zobrazení ladění má krátký formulář a dlouhý formulář. Dlouhý formulář obsahuje také všechny poznámky, které můžou být užitečné, pokud potřebujete zobrazit relační metadata nebo metadata specifická pro zprostředkovatele. K dlouhému zobrazení se dá přistupovat také z kódu:
Console.WriteLine(context.Model.ToDebugString(MetadataDebugStringOptions.LongDefault));