Propriétés d’entité
Chaque type d’entité de votre modèle a un ensemble de propriétés, que 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é correspondent 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 :
- annotations de données
- API Fluent
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
[NotMapped]
public DateTime LoadedFromDatabase { get; set; }
}
Noms de colonnes
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 extrait de code suivant :
- annotations de données
- API Fluent
public class Blog
{
[Column("blog_id")]
public int BlogId { get; set; }
public string Url { get; set; }
}
Types de données de 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 l'longueur maximale configurée, si la propriété fait partie d’une clé primaire, etc.
Par exemple, le fournisseur SQL Server associe les propriétés DateTime
aux colonnes datetime2(7)
et les propriétés string
aux colonnes nvarchar(max)
(ou aux colonnes 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
en tant que chaîne non unicode avec une longueur maximale de 200
et Rating
comme décimale avec précision de 5
et l’échelle de 2
:
- annotations de données
- API Fluent
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 indicateur 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, le 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 :
- annotations de données
- API Fluent
public class Blog
{
public int BlogId { get; set; }
[MaxLength(500)]
public string Url { get; set; }
}
Précision et échelle
Certains types de données relationnelles prennent en charge les facettes de précision et d’échelle ; ces contrôles contrôlent les valeurs qui peuvent être stockées et la quantité de stockage nécessaire pour la colonne. Les types de données qui prennent 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 decimal
et DateTime
types prennent en charge ces facettes. Pour decimal
propriétés, la précision définit le nombre maximal de chiffres nécessaires pour exprimer n’importe quelle valeur que la colonne contiendra et l’échelle définit le nombre maximal de décimales nécessaires. Pour DateTime
propriétés, la précision définit le nombre maximal de chiffres nécessaires pour exprimer des fractions de secondes et 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 précision à définir, tandis qu’un 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 14 et l’échelle 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 que la précision 3 entraîne la création d’une colonne de type datetime2(3)
:
- annotations de données
- API Fluent
public class Blog
{
public int BlogId { get; set; }
[Precision(14, 2)]
public decimal Score { get; set; }
[Precision(3)]
public DateTime LastUpdated { get; set; }
}
L’échelle n’est jamais définie sans définir la précision, de sorte que l’annotation de données pour la définition de 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 la prise 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 :
- annotations de données
- API Fluent
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é peut être considérée comme facultative s’il est valide qu’elle contienne null
. Si null
n’est pas une valeur valide à affecter à une propriété, elle est considérée comme une propriété requise. Lors du mappage à un schéma de base de données relationnelle, les propriétés requises sont créées en tant que colonnes non nullables et les propriétés facultatives sont créées en tant que colonnes nullables.
Conventions
Par convention, une propriété dont le type .NET peut contenir null sera configurée comme facultative, tandis que les propriétés dont le type .NET ne peut pas contenir null seront configurées comme requis. Par exemple, toutes les propriétés avec des types valeur .NET (int
, decimal
, bool
, etc.) sont configurées comme obligatoires, et toutes les propriétés avec des types de valeurs .NET nullables (int?
, decimal?
, bool?
, etc.) sont configurées comme facultatives.
C# 8 a introduit une nouvelle fonctionnalité appelée types de référence nullables (NRT), qui permet d’annoter les types de référence, indiquant s’il est possible pour eux de contenir ou non une valeur null. 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 nullables affectent le comportement d’EF Core de la manière suivante :
- Si les types de référence nullables sont désactivés, toutes les propriétés avec les types de référence .NET sont configurées comme facultatives par convention (par exemple,
string
). - Si les types de référence nullables sont activés, les propriétés sont configurées en fonction de la nullabilité C# de leur type .NET :
string?
sera configurée comme facultative, maisstring
sera configurée comme requise.
L’exemple suivant montre un type d’entité avec des propriétés obligatoires et facultatives, avec la fonctionnalité de référence nullable 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érences nullables est recommandée, car elle traduit la nullabilité exprimée dans le code C# vers le modèle EF Core et la base de données, et évite d'avoir à utiliser l'API Fluent ou des annotations de données pour exprimer inutilement le même concept.
Remarque
Soyez prudent lors de l’activation des types de référence nullables sur un projet existant : les propriétés de type de référence précédemment configurées comme facultatives seront désormais configurées comme obligatoires, sauf si elles sont explicitement annotées pour être nullables. 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 la nullabilité des colonnes de la base de données.
Pour plus d’informations sur les types de référence nullables et leur utilisation avec EF Core, consultez la page de documentation dédiée pour cette fonctionnalité.
Configuration explicite
Une propriété qui serait facultative par convention peut être configurée pour être requise comme suit :
- annotations de données
- API Fluent
public class Blog
{
public int BlogId { get; set; }
[Required]
public string Url { get; set; }
}
Classements des colonnes
Un classement peut être défini sur les colonnes de texte, en déterminant comment elles sont comparées et ordonné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 de colonne
Vous pouvez définir un commentaire de texte arbitraire défini sur la colonne de base de données, ce qui vous permet de documenter votre schéma dans la base de données :
- annotations de données
- API Fluent
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 place d’abord les colonnes clés primaires, suivies des propriétés du type d’entité et des types possédés, et enfin des propriétés issues de types de base. Toutefois, vous pouvez spécifier un ordre de colonne différent :
- annotations de données
- API Fluent
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 l’ordre effectué avec des attributs, notamment la résolution des conflits lorsque des attributs sur différentes propriétés spécifient le même numéro de commande.
Notez que, dans le cas général, la plupart des bases de données prennent uniquement en charge les colonnes de classement lorsque la table est créée. Cela signifie que l’attribut d’ordre des colonnes ne peut pas être utilisé pour réorganiser les colonnes d’une table existante.