Mapování atributů (neboli datových poznámek) pro relace

Atributy mapování se používají k úpravě nebo přepsání konfigurace zjištěné konvencemi vytváření modelů. Konfigurace prováděná mapováním atributů může být přepsána rozhraním API pro sestavení modelu použitém v OnModelCreating.

Důležité

Tento dokument popisuje pouze atributy mapování v kontextu konfigurace relace. Další použití atributů mapování najdete v příslušných částech širší dokumentace k modelování.

Návod

Níže uvedený kód najdete v MappingAttributes.cs.

Kde získat atributy mapování

Mnoho atributů mapování pochází z oborů názvů System.ComponentModel.DataAnnotations a System.ComponentModel.DataAnnotations.Schema . Atributy v těchto oborech názvů jsou zahrnuty jako součást základní architektury ve všech podporovaných verzích .NET, a proto nevyžadují instalaci žádných dalších balíčků NuGet. Tyto atributy mapování se běžně nazývají "datové poznámky" a používají se různými architekturami, včetně EF Core, EF6, ASP.NET Core MVC atd. Používají se také k ověření.

Použití datových poznámek v mnoha technologiích a pro mapování i ověřování vedlo k rozdílům v sémantice napříč technologiemi. Všechny nové atributy mapování navržené pro EF Core jsou teď specifické pro EF Core, čímž zůstává jejich sémantika a použití jednoduché a jasné. Tyto atributy jsou obsaženy v balíčku NuGet Microsoft.EntityFrameworkCore.Abstractions . Tento balíček je součástí závislosti při každém použití hlavního balíčku Microsoft.EntityFrameworkCore nebo jednoho z přidružených balíčků zprostředkovatele databáze. Balíček Abstractions je však lehký balíček, na který lze odkazovat přímo pomocí kódu aplikace, aniž by bylo nutné načíst celé EF Core a všechny jeho závislosti.

PovinnýAtribut

RequiredAttribute je použita u vlastnosti, která označuje, že vlastnost nemůže být null. V kontextu relací [Required] se obvykle používá u vlastnosti cizího klíče. Tímto nemůže být cizí klíč nulový, čímž se stává vztah povinným. Například u následujících typů je vlastnost Post.BlogId nastavena jako nenulová a relace je povinná.

public class Blog
{
    public string Id { get; set; }
    public List<Post> Posts { get; } = new();
}

public class Post
{
    public int Id { get; set; }

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

    public Blog Blog { get; init; }
}

Poznámka:

Při použití nulovatelných referenčních typů C# je vlastnost v tomto příkladu již nenulovatelná, což znamená, že BlogId atribut nebude mít žádný účinek.[Required]

[Required] umístěno na závislé navigaci má stejný účinek. Poté, co je cizí klíč nastaven jako nezánikový, což znamená, že vztah je povinný. Příklad:

public class Blog
{
    public string Id { get; set; }
    public List<Post> Posts { get; } = new();
}

public class Post
{
    public int Id { get; set; }

    public string BlogId { get; set; }

    [Required]
    public Blog Blog { get; init; }
}

Pokud je [Required] nalezena v závislé navigaci a vlastnost cizího klíče je v režimu stínu, pak je stínová vlastnost nastavena jako nenulová, čímž je vztah vyžadován. Příklad:

public class Blog
{
    public string Id { get; set; }
    public List<Post> Posts { get; } = new();
}

public class Post
{
    public int Id { get; set; }

    [Required]
    public Blog Blog { get; init; }
}

Poznámka:

Použití [Required] na hlavní navigační straně relace nemá žádný vliv.

ForeignKeyAttribute

ForeignKeyAttribute se používá k propojení vlastnosti cizího klíče s jeho navigacemi. [ForeignKey] lze umístit na vlastnost cizího klíče s názvem závislé navigace. Příklad:

public class Blog
{
    public string Id { get; set; }
    public List<Post> Posts { get; } = new();
}

public class Post
{
    public int Id { get; set; }

    [ForeignKey(nameof(Blog))]
    public string BlogKey { get; set; }

    public Blog Blog { get; init; }
}

[ForeignKey] Nebo lze umístit do závislé nebo hlavní navigace s názvem vlastnosti, která se má použít jako cizí klíč. Příklad:

public class Blog
{
    public string Id { get; set; }
    public List<Post> Posts { get; } = new();
}

public class Post
{
    public int Id { get; set; }

    public string BlogKey { get; set; }

    [ForeignKey(nameof(BlogKey))]
    public Blog Blog { get; init; }
}

Když [ForeignKey] se umístí na navigaci a zadaný název neodpovídá žádnému názvu vlastnosti, vytvoří se stínová vlastnost s tímto názvem, která bude fungovat jako cizí klíč. Příklad:

public class Blog
{
    public string Id { get; set; }
    public List<Post> Posts { get; } = new();
}

public class Post
{
    public int Id { get; set; }

    [ForeignKey("BlogKey")]
    public Blog Blog { get; init; }
}

InversePropertyAttribute

InversePropertyAttribute slouží k propojení navigace s její inverzní verzí. Například v následujících typech entit existují dvě relace mezi Blog a Post. Bez jakékoli konfigurace ef konvence nemohou určit, které navigace mezi těmito dvěma typy by se měly spárovat. Přidání [InverseProperty] do jedné z spárovaných navigačních panelů řeší tuto nejednoznačnost a umožňuje EF sestavit model.

public class Blog
{
    public int Id { get; set; }

    [InverseProperty("Blog")]
    public List<Post> Posts { get; } = new();

    public int FeaturedPostId { get; set; }
    public Post FeaturedPost { get; set; }
}

public class Post
{
    public int Id { get; set; }
    public int BlogId { get; set; }

    public Blog Blog { get; init; }
}

Důležité

[InverseProperty] je potřeba pouze v případě, že existuje více než jeden vztah mezi stejnými typy. S jednou relací se obě navigace spárují automaticky.

OdstranitAtributChování

Podle konvence EF používá ClientSetNullDeleteBehavior pro volitelné vztahy a Cascade chování požadovaných vztahů. To lze změnit umístěním DeleteBehaviorAttribute na jeden z navigačních prvků relace. Příklad:

public class Blog
{
    public int Id { get; set; }
    public List<Post> Posts { get; } = new();
}

public class Post
{
    public int Id { get; set; }
    public int BlogId { get; set; }

    [DeleteBehavior(DeleteBehavior.Restrict)]
    public Blog Blog { get; init; }
}

Další informace o kaskádovém chování najdete v tématu Kaskádové odstranění.