Claves
Una clave actúa como un identificador único para cada instancia de entidad. La mayoría de las entidades de EF tienen una sola clave, que se asigna al concepto de una clave principal en bases de datos relacionales (para entidades sin claves, consulte Entidades sin claves). Las entidades pueden tener claves adicionales además de la clave principal (consulte Claves alternativas para más información).
Configurar una clave principal
Por convención, una propiedad llamada Id
o <type name>Id
se configurará como clave principal de una entidad.
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; }
}
Nota:
Los tipos de entidad en propiedad usan reglas diferentes para definir claves.
Puede configurar una única propiedad para que sea la clave principal de una entidad de la siguiente manera:
internal class Car
{
[Key]
public string LicensePlate { get; set; }
public string Make { get; set; }
public string Model { get; set; }
}
También puede configurar varias propiedades para que sean la clave de una entidad; esto se conoce como clave compuesta. Las convenciones solo configurarán una clave compuesta en casos específicos, como para una colección de tipos en propiedad.
Nota:
El atributo [PrimaryKey]
se introdujo en EF Core 7.0. Usar la API de Fluent en versiones anteriores.
[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; }
}
Generación de valor
En el caso de las claves principales numéricas y GUID no compuestas, EF Core configura automáticamente la generación de valores por convención. Por ejemplo, una clave principal numérica en SQL Server se configura automáticamente para que sea una columna IDENTITY. Para más información, consulte la documentación sobre la generación de valores y la guía sobre las estrategias específicas de asignación de herencia.
Nombre de la clave principal
Por convención, las claves principales de las bases de datos relacionales se crean con el nombre PK_<type name>
. Puede configurar el nombre de la restricción de clave principal de la siguiente manera:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.HasKey(b => b.BlogId)
.HasName("PrimaryKey_BlogId");
}
Tipos y valores de clave
Aunque EF Core admite el uso de propiedades de cualquier tipo simple como clave principal, incluyendo string
, Guid
, byte[]
y otras, no todas las bases de datos admiten todos los tipos como claves. En algunos casos, los valores de clave se pueden convertir automáticamente a un tipo admitido; en caso contrario, la conversión se debe especificar manualmente.
Las propiedades de clave siempre deben tener un valor no predeterminado al agregar una nueva entidad al contexto, pero algunos tipos serán generados por la base de datos. En ese caso, con fines de seguimiento, EF intentará generar un valor temporal cuando se agregue la entidad. Después de que se llame a SaveChanges, el valor temporal será reemplazado por el valor generado por la base de datos.
Importante
Si el valor de una propiedad clave es generado por la base de datos y se especificó un valor no predeterminado al agregar la entidad, EF asumirá que la entidad ya existe en la base de datos e intentará actualizarlo en lugar de insertar uno nuevo. Para evitar esto, desactive la generación de valores o consulte cómo especificar valores explícitos para las propiedades generadas.
Claves alternativas
Una clave alternativa actúa como un identificador único alternativo para cada instancia de entidad además de la clave principal; se puede usar como destino de una relación. Cuando se usa una base de datos relacional, esto da lugar al concepto de un índice o restricción únicos en las columnas de clave alternativas y una o varias restricciones de clave externa que hacen referencia a las columnas.
Sugerencia
Si simplemente quiere forzar que los valores de una columna sean únicos, defina un índice único en lugar de una clave alternativa (consulte Índices). En EF, las claves alternativas son de solo lectura y proporcionan semántica adicional sobre índices únicos, ya que se pueden usar como destino de una clave externa.
Las claves alternativas se suelen introducir automáticamente cuando es necesario y no hace falta configurarlas manualmente. Por convención, se introduce una clave alternativa cuando identifica como destino de una relación una propiedad que no es la clave principal.
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; }
}
También puede configurar una sola propiedad para que sea una clave alternativa:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Car>()
.HasAlternateKey(c => c.LicensePlate);
}
También puede configurar varias propiedades para que sean una clave alternativa (conocida como clave compuesta alternativa):
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Car>()
.HasAlternateKey(c => new { c.State, c.LicensePlate });
}
Por último, por convención, el índice y la restricción que se introducen para una clave alternativa se denominarán AK_<type name>_<property name>
(para las claves alternativas compuestas <property name>
se convierte en una lista de nombres de propiedad separados por guiones bajos). Puede configurar el nombre del índice de la clave alternativa y la restricción única:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Car>()
.HasAlternateKey(c => c.LicensePlate)
.HasName("AlternateKey_LicensePlate");
}