en el código del marco de la entidad primero, cómo usar KeyAttribute en múltiples columnas

93

Estoy creando un modelo POCO para usar con el código del marco de la entidad primero CTP5. Estoy usando la decoración para hacer un mapa de propiedades en una columna PK. Pero, ¿cómo puedo definir un PK en más de una columna, y específicamente, cómo puedo controlar el orden de las columnas en el índice? ¿Es el resultado del orden de propiedades en la clase?

¡Gracias!

GilShalit
fuente

Respuestas:

153

Puede especificar el orden de las columnas en los atributos, por ejemplo:

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 está utilizando el Findmétodo de a DbSet, debe tener en cuenta este orden para los parámetros clave.

Slauma
fuente
1
InvalidOperationException: el tipo de entidad 'XXX' tiene una clave primaria compuesta definida con anotaciones de datos. Para configurar la clave primaria compuesta, use una API fluida.
Luca Ziegler
55

Para completar la respuesta correcta enviada por Slauma, también puede usar el método HasKey para especificar un orden para las claves primarias compuestas:

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
fuente
2
Gracias, ambos métodos funcionan bien. Prefiero los atributos porque estoy generando mis clases a partir del código y los atributos son mucho más concisos.
GilShalit
Personalmente, también agrego Propety (x ...). HasColumnOrder (0 ... n) a cada una de las propiedades con clave. ¿Eso es bueno, malo, indiferente?
Suamere
7

Si, como yo, prefieres usar un archivo de configuración, puedes hacerlo de esta manera (según el ejemplo 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, debe agregar el archivo de configuración a su contexto:

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

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

Utilizar como objeto anónimo:

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