Attributi di mapping (nota anche come annotazioni dei dati) per le relazioni

Gli attributi di mapping vengono usati per modificare o ignorare la configurazione individuata dalle convenzioni di compilazione del modello. La configurazione eseguita dagli attributi di mapping può essere sottoposta a override dall'API di compilazione del modello usata in OnModelCreating.

Importante

Questo documento illustra solo gli attributi di mapping nel contesto della configurazione delle relazioni. Altri usi degli attributi di mapping sono trattati nelle sezioni pertinenti della documentazione di modellazione più ampia.

Suggerimento

Il codice seguente è disponibile in MappingAttributes.cs.

Dove ottenere gli attributi di mapping

Molti attributi di mapping provengono dagli spazi dei nomi System.ComponentModel.DataAnnotations e System.ComponentModel.DataAnnotations.Schema . Gli attributi in questi spazi dei nomi sono inclusi come parte del framework di base in tutte le versioni supportate di .NET e pertanto non richiedono l'installazione di pacchetti NuGet aggiuntivi. Questi attributi di mapping sono comunemente denominati "annotazioni dei dati" e vengono usati da un'ampia gamma di framework, tra cui EF Core, EF6, ASP.NET Core MVC e così via. Vengono usati anche per la convalida.

L'uso delle annotazioni dei dati in molte tecnologie e per mapping e convalida ha portato a differenze nella semantica tra le tecnologie. Tutti i nuovi attributi di mapping progettati per EF Core sono ora specifici di EF Core, mantenendo così la semantica e usando semplici e chiari. Questi attributi sono contenuti nel pacchetto NuGet Microsoft.EntityFrameworkCore.Abstractions . Questo pacchetto viene incluso come dipendenza ogni volta che viene usato il pacchetto Microsoft.EntityFrameworkCore principale o uno dei pacchetti del provider di database associati. Tuttavia, il pacchetto Astrazioni è un pacchetto leggero a cui è possibile fare riferimento direttamente dal codice dell'applicazione senza inserire tutte le dipendenze di EF Core e le relative dipendenze.

Requiredattribute

RequiredAttribute viene applicato a una proprietà per indicare che la proprietà non può essere null. Nel contesto delle relazioni, [Required] viene in genere usato in una proprietà di chiave esterna. In questo modo la chiave esterna non è nullable, rendendo quindi necessaria la relazione. Ad esempio, con i tipi seguenti, la Post.BlogId proprietà viene resa non nullable e la relazione diventa obbligatoria.

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

Nota

Quando si usano tipi di riferimento nullable C#, la BlogId proprietà in questo esempio è già non nullable, il che significa che l'attributo [Required] non avrà alcun effetto.

[Required] posizionato sulla navigazione dipendente ha lo stesso effetto. Ovvero, rendendo la chiave esterna non nullable e rendendo quindi necessaria la relazione. Ad esempio:

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

Se [Required] viene trovato nella struttura di spostamento dipendente e la proprietà della chiave esterna è in stato di ombreggiatura, la proprietà shadow viene resa non nullable, rendendo quindi necessaria la relazione. Ad esempio:

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

Nota

L'uso [Required] sul lato di spostamento principale di una relazione non ha alcun effetto.

ForeignKeyAttribute

ForeignKeyAttribute viene utilizzato per connettere una proprietà di chiave esterna con i relativi spostamenti. [ForeignKey] può essere inserito nella proprietà di chiave esterna con il nome della struttura di spostamento dipendente. Ad esempio:

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

In alternativa, [ForeignKey] può essere inserito nella struttura di spostamento dipendente o principale con il nome della proprietà da usare come chiave esterna. Ad esempio:

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

Quando [ForeignKey] viene posizionato in una struttura di spostamento e il nome specificato non corrisponde ad alcun nome di proprietà, verrà creata una proprietà shadow con tale nome per fungere da chiave esterna. Ad esempio:

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 viene usato per connettere una struttura di spostamento con il relativo inverso. Nei tipi di entità seguenti, ad esempio, esistono due relazioni tra Blog e Post. Senza alcuna configurazione, le convenzioni di Entity Framework non possono determinare quali spostamenti tra i due tipi devono essere associati. L'aggiunta [InverseProperty] a uno degli spostamenti associati risolve questa ambiguità e consente a ENTITY Framework di compilare il modello.

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

Importante

[InverseProperty] è necessario solo quando è presente più di una relazione tra gli stessi tipi. Con una singola relazione, le due spostamenti vengono abbinate automaticamente.

DeleteBehaviorAttribute

Per convenzione, Entity Framework usa per ClientSetNullDeleteBehavior le relazioni facoltative e il Cascade comportamento per le relazioni necessarie. Questa operazione può essere modificata posizionando su DeleteBehaviorAttribute uno degli spostamenti della relazione. Ad esempio:

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

Per altre informazioni sui comportamenti a catena, vedere Eliminazione a catena .