Teclas
Una clave actúa como identificador único para cada instancia de entidad. La mayoría de las entidades de EF tienen una clave única, que se asigna al concepto de clave principal en bases de datos relacionales (para entidades sin claves, vea Entidades sin clave). Las entidades pueden tener claves adicionales más allá de la clave principal (consulte Claves alternativas para obtener más información).
Configuración de una clave principal
Por convención, una propiedad denominada 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 de propiedad usan reglas diferentes para definir claves.
Puede configurar una sola propiedad para que sea la clave principal de una entidad como se muestra a continuación:
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, lo que se conoce como clave compuesta. Las claves compuestas solo se pueden configurar mediante la API Fluent; las convenciones nunca configurarán una clave compuesta y no se pueden usar anotaciones de datos para configurar una.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Car>()
.HasKey(c => new { c.State, c.LicensePlate });
}
Generación de valor
En el caso de las claves principales numéricas y GUID no compuestas, EF Core configurar la generación de valores automáticamente 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.
Nombre de clave principal
Por convención, en las bases de datos relacionales, las claves principales 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 primitivo como clave principal, incluidos , y otros, no todas las bases de datos admiten todos stringGuid los tipos como byte[] claves. En algunos casos, los valores de clave se pueden convertir automáticamente a un tipo admitido; de lo 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 la base de datos generará algunos tipos. En ese caso, EF intentará generar un valor temporal cuando la entidad se agrega con fines de seguimiento. Después de llamar a SaveChanges, el valor temporal se reemplazará por el valor generado por la base de datos.
Importante
Si una propiedad de clave tiene su valor generado por la base de datos y se especifica un valor no predeterminado cuando se agrega una entidad, EF asumirá que la entidad ya existe en la base de datos e intentará actualizarla en lugar de insertar una nueva. Para evitarlo, desactive la generación de valores o vea cómo especificar valores explícitos para las propiedades generadas.
Claves alternativas
Una clave alternativa actúa como 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 se asigna 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 solo desea aplicar la unidad en una columna, defina un índice único en lugar de una clave alternativa (vea Índices). En EF, las claves alternativas son de solo lectura y proporcionan semántica adicional sobre índices únicos porque se pueden usar como destino de una clave externa.
Las claves alternativas se suelen introducir automáticamente cuando es necesario y no es necesario configurarlas manualmente. Por convención, se introduce una clave alternativa cuando se identifica una propiedad que no es la clave principal como destino de una relación.
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 alternativa compuesta):
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 (para las claves alternativas compuestas se convierte en una lista separada por caracteres de subrayado de nombres AK_<type name>_<property name><property name> de propiedad). Puede configurar el nombre del índice y la restricción unique de la clave alternativa:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Car>()
.HasAlternateKey(c => c.LicensePlate)
.HasName("AlternateKey_LicensePlate");
}