Propriétés de l’entité

Chaque type d’entité de votre modèle a un ensemble de propriétés qu’EF Core lit et écrit à partir de la base de données. Si vous utilisez une base de données relationnelle, les propriétés d’entité mappent aux colonnes de table.

Propriétés incluses et exclues

Par convention, toutes les propriétés publiques ayant un getter et un setter seront incluses dans le modèle.

Les propriétés spécifiques peuvent être exclues comme suit :

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    [NotMapped]
    public DateTime LoadedFromDatabase { get; set; }
}

Noms de colonne

Par convention, lors de l’utilisation d’une base de données relationnelle, les propriétés d’entité sont mappées aux colonnes de table portant le même nom que la propriété.

Si vous préférez configurer vos colonnes avec différents noms, vous pouvez le faire comme l’extrait de code suivant :

public class Blog
{
    [Column("blog_id")]
    public int BlogId { get; set; }

    public string Url { get; set; }
}

Types données colonne

Lorsque vous utilisez une base de données relationnelle, le fournisseur de base de données sélectionne un type de données basé sur le type .NET de la propriété. Il prend également en compte d’autres métadonnées, telles que la longueur maximale configurée, si la propriété fait partie d’une clé primaire, etc.

Par exemple, SQL Server mappe les propriétés DateTime aux colonnes datetime2(7) et les propriétés string aux colonnes nvarchar(max) (ou à nvarchar(450) pour les propriétés utilisées comme clé).

Vous pouvez également configurer vos colonnes pour spécifier un type de données exact pour une colonne. Par exemple, le code suivant configure Url comme une chaîne non unicode avec une longueur maximale de 200 et Rating comme décimale avec une précision de 5 et une mise à l’échelle de 2 :

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

    [Column(TypeName = "varchar(200)")]
    public string Url { get; set; }

    [Column(TypeName = "decimal(5, 2)")]
    public decimal Rating { get; set; }
}

Longueur maximale

La configuration d’une longueur maximale fournit un conseil au fournisseur de base de données sur le type de données de colonne approprié à choisir pour une propriété donnée. La longueur maximale s’applique uniquement aux types de données de tableau, tels que string et byte[].

Remarque

Entity Framework n’effectue aucune validation de longueur maximale avant de transmettre des données au fournisseur. Il incombe au fournisseur ou au magasin de données de valider le cas échéant. Par exemple, lors du ciblage de SQL Server, un dépassement de la longueur maximale entraîne une exception, car le type de données de la colonne sous-jacente n’autorise pas le stockage de données excédentaires.

Dans l’exemple suivant, la configuration d’une longueur maximale de 500 entraîne la création d’une colonne de type nvarchar(500) sur SQL Server :

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

    [MaxLength(500)]
    public string Url { get; set; }
}

Précision et mise à l’échelle

Certains types de données relationnelles prennent en charge les facettes de précision et de mise à l’échelle. Elles contrôlent les valeurs qui peuvent être stockées et la quantité de stockage nécessaire pour la colonne. Les types de données prenant en charge la précision et la mise à l’échelle dépendent de la base de données, mais dans la plupart des bases de données, les types decimal et DateTime prennent en charge ces facettes. Pour les propriétés decimal, la précision définit le nombre maximal de chiffres nécessaires pour exprimer n’importe quelle valeur que la colonne contient et la mise à l’échelle définit le nombre maximal de décimales nécessaires. Pour les propriétés DateTime, la précision définit le nombre maximal de chiffres nécessaires pour exprimer des fractions de secondes et la mise à l’échelle n’est pas utilisée.

Remarque

Entity Framework n’effectue aucune validation de précision ou de mise à l’échelle avant de transmettre des données au fournisseur. Il incombe au fournisseur ou au magasin de données de valider le cas échéant. Par exemple, lors du ciblage de SQL Server, une colonne de type de données datetime n’autorise pas la définition de la précision, tandis qu’un type datetime2 peut avoir une précision comprise entre 0 et 7 inclus.

Dans l’exemple suivant, la configuration de la propriété Score pour avoir une précision de 14 et une mise à l’échelle de 2 entraîne la création d’une colonne de type decimal(14,2) sur SQL Server, et la configuration de la propriété LastUpdated pour avoir une précision de 3 entraîne la création d’une colonne de type datetime2(3) :

public class Blog
{
    public int BlogId { get; set; }
    [Precision(14, 2)]
    public decimal Score { get; set; }
    [Precision(3)]
    public DateTime LastUpdated { get; set; }
}

La mise à l’échelle n’est jamais définie sans définir au préalable la précision, de sorte que l’annotation de données pour la définition de la mise à l’échelle est [Precision(precision, scale)].

Unicode

Dans certaines bases de données relationnelles, différents types existent pour représenter des données texte Unicode et non Unicode. Par exemple, dans SQL Server, nvarchar(x) est utilisé pour représenter des données Unicode dans UTF-16, tandis que varchar(x) est utilisé pour représenter des données non Unicode (mais consultez les notes sur laprise en charge d’UTF-8 dans SQL Server). Pour les bases de données qui ne prennent pas en charge ce concept, la configuration de ce concept n’a aucun effet.

Les propriétés de texte sont configurées comme Unicode par défaut. Vous pouvez configurer une colonne comme non-Unicode comme suit :

public class Book
{
    public int Id { get; set; }
    public string Title { get; set; }

    [Unicode(false)]
    [MaxLength(22)]
    public string Isbn { get; set; }
}

Propriétés obligatoires et facultatives

Une propriété est considérée comme facultative si elle peut contenir null en tant que valeur valide. Si null n’est pas une valeur valide pouvant être attribuée à une propriété, elle est considérée comme une propriété obligatoire. Lors du mappage à un schéma de base de données relationnelle, les propriétés obligatoires sont créées en tant que colonnes ne pouvant pas accepter la valeur Null et les propriétés facultatives sont créées en tant que colonnes pouvant accepter la valeur Null.

Conventions

Par convention, une propriété dont le type .NET peut contenir la valeur Null est configurée comme facultative, tandis que les propriétés dont le type .NET ne peut pas contenir la valeur Null sont configurées comme obligatoires. Par exemple, toutes les propriétés ayant des types de valeur .NET (int, decimal, bool, etc.) sont configurées comme obligatoires, et toutes les propriétés ayant des types de valeurs .NET pouvant accepter la valeur Null (int?, decimal?, bool?, etc.) sont configurées comme facultatives.

C# 8 a introduit une nouvelle fonctionnalité appelée types de référence pouvant accepter la valeur Null (NRT), ce qui permet aux types de référence d’être annotés, indiquant s’ils peuvent contenir la valeur Null ou non. Cette fonctionnalité est activée par défaut dans les nouveaux modèles de projet, mais reste désactivée dans les projets existants, sauf si elle est explicitement choisie. Les types de référence pouvant accepter la valeur Null affectent le comportement d’EF Core de la manière suivante :

  • Si les types de référence pouvant accepter la valeur Null sont désactivés, toutes les propriétés ayant des types de référence .NET sont configurées comme facultatives par convention (par exemple, string).
  • Si les types de référence pouvant accepter la valeur Null sont activés, les propriétés sont configurées en fonction de la valeur d’acceptation de la valeur Null C# de leur type .NET : string? est configuré comme facultatif, mais string est configuré en fonction des besoins.

L’exemple suivant présente un type d’entité ayant des propriétés obligatoires et facultatives, avec une fonctionnalité de référence pouvant accepter la valeur Null désactivée et activée :

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

    [Required] // Data annotations needed to configure as required
    public string FirstName { get; set; }

    [Required] // Data annotations needed to configure as required
    public string LastName { get; set; }

    public string MiddleName { get; set; } // Optional by convention
}

L’utilisation de types de référence pouvant accepter la valeur Null est recommandée, car elle transfère l’acceptation de la valeur Null exprimée en code C# au modèle d’EF Core et à la base de données, et évite l’utilisation de l’API Fluent ou des annotations de données pour exprimer le même concept deux fois.

Remarque

Soyez prudent lors de l’activation des types de référence pouvant accepter la valeur Null sur un projet existant : les propriétés de type de référence précédemment configurées comme facultatives sont désormais configurées comme obligatoires, sauf si elles sont explicitement annotées pour pouvant accepter la valeur Null. Lors de la gestion d’un schéma de base de données relationnelle, cela peut entraîner la génération de migrations qui modifient l’acceptation de la valeur Null de la colonne de la base de données.

Pour plus d’informations sur les types de référence pouvant accepter la valeur Null et leur utilisation avec EF Core, consultez la page de documentation dédiée à cette fonctionnalité.

Configuration explicite

Une propriété qui serait facultative par convention peut être configurée pour être obligatoire comme suit :

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

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

Classements des colonnes

Un classement peut être défini sur des colonnes de texte, en déterminant comment elles sont comparées et triées. Par exemple, l’extrait de code suivant configure une colonne SQL Server pour qu’elle ne respecte pas la casse :

modelBuilder.Entity<Customer>().Property(c => c.Name)
    .UseCollation("SQL_Latin1_General_CP1_CI_AS");

Si toutes les colonnes d’une base de données doivent utiliser un certain classement, définissez plutôt le classement au niveau de la base de données.

Vous trouverez des informations générales sur la prise en charge EF Core des classement dans la page de documentation de classement.

Commentaires des colonnes

Vous pouvez définir un commentaire de texte arbitraire qui est défini sur la colonne d’une base de données, ce qui vous permet de documenter votre schéma dans la base de données :

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

    [Comment("The URL of the blog")]
    public string Url { get; set; }
}

Ordre des colonnes

Par défaut, lors de la création d’une table avec Migrations, EF Core classe d’abord les colonnes clés primaires, suivies des propriétés du type d’entité et des types détenus, et enfin des propriétés à partir des types de base. Toutefois, vous pouvez spécifier un ordre de colonne différent :

public class EntityBase
{
    [Column(Order = 0)]
    public int Id { get; set; }
}

public class PersonBase : EntityBase
{
    [Column(Order = 1)]
    public string FirstName { get; set; }

    [Column(Order = 2)]
    public string LastName { get; set; }
}

public class Employee : PersonBase
{
    public string Department { get; set; }
    public decimal AnnualSalary { get; set; }
}

L’API Fluent peut être utilisée pour remplacer le classement effectué avec des attributs, y compris pour résoudre les conflits lorsque des attributs de propriétés différentes spécifient le même numéro d’ordre.

Notez qu’en général, la plupart des bases de données prennent uniquement en charge le classement des colonnes lors de la création de la table. Cela signifie que l’attribut d’ordre des colonnes ne peut pas être utilisé pour réordonner les colonnes d’une table existante.