Clés

Une clé sert d’identificateur unique pour chaque instance d’entité. La plupart des entités dans EF ont une clé unique, qui correspond au concept d’une clé primaire dans les bases de données relationnelles (pour les entités sans clés, consultez entités sans clé). Les entités peuvent avoir des clés supplémentaires au-delà de la clé primaire (consultez autres clés pour plus d’informations).

Configuration d’une clé primaire

Par convention, une propriété nommée Id ou <type name>Id sera configurée comme clé primaire d’une entité.

internal class Car
{
    public string Id { get; set; }

    public string Make { get; set; }
    public string Model { get; set; }
}

internal class Truck
{
    public string TruckId { get; set; }

    public string Make { get; set; }
    public string Model { get; set; }
}

Remarque

Types d’entités détenues utiliser différentes règles pour définir des clés.

Vous pouvez configurer une propriété unique pour qu’elle soit la clé primaire d’une entité comme suit :

internal class Car
{
    [Key]
    public string LicensePlate { get; set; }

    public string Make { get; set; }
    public string Model { get; set; }
}

Vous pouvez également configurer plusieurs propriétés pour qu’elles soient la clé d’une entité. Il s’agit d’une clé composite. Les conventions configurent uniquement une clé composite dans des cas spécifiques, comme pour une collection de types appartenant.

Remarque

L’attribut [PrimaryKey] a été introduit dans EF Core 7.0. Utilisez l’API Fluent dans les versions antérieures.

[PrimaryKey(nameof(State), nameof(LicensePlate))]
internal class Car
{
    public string State { get; set; }
    public string LicensePlate { get; set; }

    public string Make { get; set; }
    public string Model { get; set; }
}

Génération de valeur

Pour les clés primaires numériques et GUID non composites, EF Core configure la génération de valeurs pour vous par convention. Par exemple, une clé primaire numérique dans SQL Server est automatiquement configurée pour être une colonne IDENTITY. Pour plus d’informations, consultez la documentation relative aux de génération de valeurs et conseils pour des stratégies de mappage d’héritage spécifiques.

Nom de clé primaire

Par convention, les clés primaires des bases de données relationnelles sont créées avec le nom PK_<type name>. Vous pouvez configurer le nom de la contrainte de clé primaire comme suit :

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .HasKey(b => b.BlogId)
        .HasName("PrimaryKey_BlogId");
}

Types de clés et valeurs

Bien qu’EF Core prenne en charge l’utilisation de propriétés de n’importe quel type primitif comme clé primaire, notamment string, Guid, byte[] et d’autres, toutes les bases de données ne prennent pas en charge tous les types en tant que clés. Dans certains cas, les valeurs de clé peuvent être converties automatiquement en type pris en charge, sinon la conversion doit être spécifiée manuellement.

Les propriétés de clé doivent toujours avoir une valeur non par défaut lors de l’ajout d’une nouvelle entité au contexte, mais certains types seront générés par la base de données. Dans ce cas, EF tente de générer une valeur temporaire lorsque l’entité est ajoutée à des fins de suivi. Une fois SaveChanges est appelée la valeur temporaire sera remplacée par la valeur générée par la base de données.

Important

Si une propriété de clé a sa valeur générée par la base de données et qu’une valeur non par défaut est spécifiée lorsqu’une entité est ajoutée, EF suppose que l’entité existe déjà dans la base de données et tente de la mettre à jour au lieu d’en insérer une nouvelle. Pour éviter cela, désactivez la génération de valeurs ou consultez comment spécifier des valeurs explicites pour les propriétés générées.

Clés secondaires

Une autre clé sert d’identificateur unique de remplacement pour chaque instance d’entité en plus de la clé primaire ; elle peut être utilisée comme cible d’une relation. Lors de l’utilisation d’une base de données relationnelle, cela correspond au concept d’index/contrainte unique sur la ou les autres colonnes clés et une ou plusieurs contraintes de clé étrangère qui référencent la ou les colonnes.

Conseil

Si vous souhaitez simplement appliquer l’unicité sur une colonne, définissez un index unique plutôt qu’une autre clé (voir Index). Dans EF, les clés alternatives sont en lecture seule et fournissent des sémantiques supplémentaires sur des index uniques, car elles peuvent être utilisées comme cible d’une clé étrangère.

Les autres clés sont généralement introduites pour vous si nécessaire et vous n’avez pas besoin de les configurer manuellement. Par convention, une autre clé est introduite pour vous lorsque vous identifiez une propriété qui n’est pas la clé primaire comme cible d’une relation.

internal class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Post>()
            .HasOne(p => p.Blog)
            .WithMany(b => b.Posts)
            .HasForeignKey(p => p.BlogUrl)
            .HasPrincipalKey(b => b.Url);
    }
}

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

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public string BlogUrl { get; set; }
    public Blog Blog { get; set; }
}

Vous pouvez également configurer une propriété unique pour qu’elle soit une autre clé :

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Car>()
        .HasAlternateKey(c => c.LicensePlate);
}

Vous pouvez également configurer plusieurs propriétés pour qu’elles soient une autre clé (appelée clé alternative composite) :

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Car>()
        .HasAlternateKey(c => new { c.State, c.LicensePlate });
}

Enfin, par convention, l’index et la contrainte introduits pour une autre clé seront nommés AK_<type name>_<property name> (pour les clés alternatives composites <property name> devient une liste séparée par un trait de soulignement des noms de propriétés). Vous pouvez configurer le nom de l’index et de la contrainte unique de la clé alternative :

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Car>()
        .HasAlternateKey(c => c.LicensePlate)
        .HasName("AlternateKey_LicensePlate");
}