dans le code du framework d'entité d'abord, comment utiliser KeyAttribute sur plusieurs colonnes

93

Je crée un modèle POCO à utiliser avec le code de cadre d'entité d'abord CTP5. J'utilise la décoration pour créer une carte de propriété sur une colonne PK. Mais comment puis-je définir un PK sur plus d'une colonne, et plus précisément, comment puis-je contrôler l'ordre des colonnes dans l'index? Est-ce le résultat de l'ordre des propriétés dans la classe?

Merci!

GilShalit
la source

Réponses:

153

Vous pouvez spécifier l'ordre des colonnes dans les attributs, par exemple:

public class MyEntity
{
    [Key, Column(Order=0)]
    public int MyFirstKeyProperty { get; set; }

    [Key, Column(Order=1)]
    public int MySecondKeyProperty { get; set; }

    [Key, Column(Order=2)]
    public string MyThirdKeyProperty { get; set; }

    // other properties
}

Si vous utilisez la Findméthode a, DbSetvous devez prendre en compte cet ordre pour les paramètres clés.

Slauma
la source
1
InvalidOperationException: le type d'entité 'XXX' a une clé primaire composite définie avec des annotations de données. Pour définir la clé primaire composite, utilisez l'API fluent.
Luca Ziegler
55

Pour compléter la bonne réponse soumise par Slauma, vous pouvez également utiliser la méthode HasKey pour spécifier un ordre pour les clés primaires composites:

public class User
{        
    public int UserId { get; set; }       
    public string Username { get; set; }        
}        

public class Ctp5Context : DbContext
{
    public DbSet<User> Users { get; set; }        

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>().HasKey(u => new 
        { 
            u.UserId, 
            u.Username 
        });
    }
}
Morteza Manavi
la source
2
Merci - les deux méthodes fonctionnent bien. Je préfère les attributs car je génère mes classes à partir de code et les attributs sont beaucoup plus concis.
GilShalit
Personnellement, j'ajoute également la propriété (x ...). HasColumnOrder (0 ... n) à chacune des propriétés saisies. Est-ce que c'est bon, mauvais, indifférent?
Suamere
7

Si, comme moi, vous préférez utiliser un fichier de configuration, vous pouvez le faire de cette manière (sur la base de l'exemple de Manavi):

public class User
{
    public int UserId { get; set; }
    public string Username { get; set; }
}  

public class UserConfiguration : EntityTypeConfiguration<User>
{
    public UserConfiguration()
    {
        ToTable("Users");
        HasKey(x => new {x.UserId, x.Username});
    }
}

Evidemment, vous devez ajouter le fichier de configuration à votre contexte:

public class Ctp5Context : DbContext
{
    public DbSet<User> Users { get; set; }        

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
         modelBuilder.Configurations.Add(new UserConfiguration());
    }
}
Daniele Armanasco
la source
0

Utiliser comme objet anonyme:

modelBuilder.Entity<UserExamAttemptQuestion>().ToTable("Users").HasKey(o => new { o.UserId, o.Username }); 
WACS kumara
la source