no código da estrutura da entidade primeiro, como usar KeyAttribute em várias colunas

93

Estou criando um modelo POCO para usar com o código de estrutura de entidade primeiro CTP5. Estou usando a decoração para fazer um mapa de propriedade para uma coluna PK. Mas como posso definir um PK em mais de uma coluna e, especificamente, como posso controlar a ordem das colunas no índice? É o resultado da ordem das propriedades na classe?

Obrigado!

GilShalit
fonte

Respostas:

153

Você pode especificar a ordem das colunas nos atributos, por exemplo:

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
}

Se você estiver usando o Findmétodo de a, DbSetdeve levar em consideração esta ordem para os parâmetros-chave.

Slauma
fonte
1
InvalidOperationException: o tipo de entidade 'XXX' possui uma chave primária composta definida com anotações de dados. Para definir a chave primária composta, use a API fluente.
Luca Ziegler
55

Para completar a resposta correta enviada por Slauma, você também pode usar o método HasKey para especificar um pedido para chaves primárias compostas:

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
fonte
2
Obrigado - ambos os métodos funcionam bem. Eu prefiro os atributos porque estou gerando minhas classes a partir do código e os atributos são muito mais concisos.
GilShalit de
Pessoalmente, também adiciono o Propety (x ...). HasColumnOrder (0 ... n) a cada uma das propriedades codificadas. Isso é bom, ruim, indiferente?
Suamere
7

Se, como eu, você preferir usar um arquivo de configuração, pode fazer desta forma (com base no exemplo 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});
    }
}

Obviamente, você deve adicionar o arquivo de configuração ao seu contexto:

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

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

Use como um objeto anônimo:

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