Propiedades de entidad
Cada tipo de entidad del modelo tiene un conjunto de propiedades, que EF Core leerán y escribirán desde la base de datos. Si usa una base de datos relacional, las propiedades de entidad se asignan a columnas de tabla.
Propiedades incluidas y excluidas
Por convención, todas las propiedades públicas con un getter y un setter se incluirán en el modelo.
Las propiedades específicas se pueden excluir de la siguiente manera:
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
[NotMapped]
public DateTime LoadedFromDatabase { get; set; }
}
Nombres de columna
Por convención, cuando se usa una base de datos relacional, las propiedades de entidad se asignan a columnas de tabla con el mismo nombre que la propiedad .
Si prefiere configurar las columnas con nombres diferentes, puede hacerlo como fragmento de código siguiente:
public class Blog
{
[Column("blog_id")]
public int BlogId { get; set; }
public string Url { get; set; }
}
Tipos de datos de columna
Cuando se usa una base de datos relacional, el proveedor de base de datos selecciona un tipo de datos basado en el tipo .NET de la propiedad. También tiene en cuenta otros metadatos, como la longitud máxima configurada,si la propiedad forma parte de una clave principal, etc.
Por ejemplo, SQL Server asigna propiedades a columnas y propiedades a columnas (o a para propiedades que DateTimedatetime2(7) se usan como stringnvarchar(max)nvarchar(450) clave).
También puede configurar las columnas para especificar un tipo de datos exacto para una columna. Por ejemplo, el código siguiente configura como una cadena no Unicode con la longitud máxima de y como decimal con Url precisión de y escala de 200Rating52 :
public class Blog
{
public int BlogId { get; set; }
[Column(TypeName = "varchar(200)")]
public string Url { get; set; }
[Column(TypeName = "decimal(5, 2)")]
public decimal Rating { get; set; }
}
Longitud máxima
La configuración de una longitud máxima proporciona una sugerencia al proveedor de base de datos sobre el tipo de datos de columna adecuado para elegir para una propiedad determinada. La longitud máxima solo se aplica a los tipos de datos de matriz, como string y byte[] .
Nota
Entity Framework no realiza ninguna validación de longitud máxima antes de pasar datos al proveedor. Es el proveedor o almacén de datos el que debe validar si procede. Por ejemplo, al tener como destino SQL Server, si se supera la longitud máxima, se producirá una excepción, ya que el tipo de datos de la columna subyacente no permitirá almacenar datos excesivos.
En el ejemplo siguiente, la configuración de una longitud máxima de 500 hará que se cree una columna de tipo en nvarchar(500) SQL Server:
public class Blog
{
public int BlogId { get; set; }
[MaxLength(500)]
public string Url { get; set; }
}
Precisión y escala
Algunos tipos de datos relacionales admiten las facetas de precisión y escala; estos controlan qué valores se pueden almacenar y cuánto almacenamiento se necesita para la columna. Los tipos de datos que admiten precisión y escala dependen de la base de datos, pero en la mayoría de las bases de datos decimalDateTime y tipos admiten estas facetas. Para las propiedades, la precisión define el número máximo de dígitos necesarios para expresar cualquier valor que contendrá la columna y la escala define el número máximo de posiciones decimal decimales necesarias. Para las propiedades, la precisión define el número máximo de dígitos necesarios para expresar fracciones de segundos y no se DateTime usa la escala.
Nota
Entity Framework no realiza ninguna validación de precisión o escala antes de pasar datos al proveedor. Es el proveedor o almacén de datos el que debe validarlo según corresponda. Por ejemplo, al establecer SQL Server destino, una columna de tipo de datos no permite establecer la precisión, mientras que una puede tener una precisión entre 0 y datetimedatetime2 7 inclusive.
En el ejemplo siguiente, al configurar la propiedad para que tenga la precisión 14 y la escala 2, se creará una columna de tipo en SQL Server y la configuración de la propiedad para que tenga la precisión 3 provocará una columna de Scoredecimal(14,2) tipo LastUpdateddatetime2(3) :
Nota
La anotación de datos para configurar la precisión y la escala se introdujo en EF Core 6.0.
public class Blog
{
public int BlogId { get; set; }
[Precision(14, 2)]
public decimal Score { get; set; }
[Precision(3)]
public DateTime LastUpdated { get; set; }
}
La escala nunca se define sin definir primero la precisión, por lo que la anotación de datos para definir la escala es [Precision(precision, scale)] .
Unicode
En algunas bases de datos relacionales, existen tipos diferentes para representar datos de texto Unicode y no Unicode. Por ejemplo, en SQL Server, se usa para representar datos Unicode en UTF-16, mientras que se usa para representar datos no Unicode (pero vea las notas sobre la compatibilidad con nvarchar(x)varchar(x)nvarchar(x)de SQL Server ). Para las bases de datos que no admiten este concepto, configurar esto no tiene ningún efecto.
Las propiedades de texto se configuran como Unicode de forma predeterminada. Puede configurar una columna como no Unicode de la siguiente manera:
Nota
La anotación de datos para configurar Unicode se introdujo en EF Core 6.0.
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
[Unicode(false)]
[MaxLength(22)]
public string Isbn { get; set; }
}
Propiedades obligatorias y opcionales
Una propiedad se considera opcional si es válida para que contenga null . Si no es un valor válido que se va a asignar a una propiedad, se considera null una propiedad obligatoria. Al asignar a un esquema de base de datos relacional, las propiedades necesarias se crean como columnas que no aceptan valores NULL y las propiedades opcionales se crean como columnas que aceptan valores NULL.
Convenciones
Por convención, una propiedad cuyo tipo de .NET puede contener NULL se configurará como opcional, mientras que las propiedades cuyo tipo de .NET no puede contener null se configurarán según sea necesario. Por ejemplo, todas las propiedades con tipos de valor de .NET ( intdecimal , , , bool etc.) se configuran según sea necesario y todas las propiedades con tipos de valor .NET que aceptan valores NULL ( int?decimal? , , , bool? etc.) se configuran como opcionales.
C# 8 introdujo una nueva característica denominada tipos de referencia que aceptan valores NULL (NRT),que permite anotar los tipos de referencia, lo que indica si es válido que contengan null o no. Esta característica está deshabilitada de forma predeterminada y afecta EF Core comportamiento de la siguiente manera:
- Si los tipos de referencia que aceptan valores NULL están deshabilitados (valor predeterminado), todas las propiedades con tipos de referencia de .NET se configuran como opcionales por convención (por ejemplo,
string). - Si se habilitan los tipos de referencia que aceptan valores NULL, las propiedades se configurarán en función de la nulabilidad de C# de su tipo .NET: se configurará como opcional, pero se configurará según
string?stringsea necesario.
En el ejemplo siguiente se muestra un tipo de entidad con propiedades obligatorias y opcionales, con la característica de referencia que acepta valores NULL deshabilitada (valor predeterminado) y habilitada:
public class CustomerWithoutNullableReferenceTypes
{
public int Id { get; set; }
[Required] // Data annotations needed to configure as required
public string FirstName { get; set; }
[Required]
public string LastName { get; set; } // Data annotations needed to configure as required
public string MiddleName { get; set; } // Optional by convention
}
Se recomienda usar tipos de referencia que aceptan valores NULL, ya que fluye la nulabilidad expresada en el código de C# al modelo de EF Core y a la base de datos, y obvia el uso de la API de Fluent o anotaciones de datos para expresar el mismo concepto dos veces.
Nota
Tenga cuidado al habilitar tipos de referencia que aceptan valores NULL en un proyecto existente: las propiedades de tipo de referencia que se configuraron anteriormente como opcionales ahora se configurarán como necesarias, a menos que se anoten explícitamente para que sean que aceptan valores NULL. Al administrar un esquema de base de datos relacional, esto puede provocar que se generen migraciones que modifiquen la nulabilidad de la columna de base de datos.
Para obtener más información sobre los tipos de referencia que aceptan valores NULL y cómo usarlos con EF Core, consulte la página de documentación dedicada de esta característica.
Configuración explícita
Una propiedad que sería opcional por convención se puede configurar para que sea necesaria como se muestra a continuación:
public class Blog
{
public int BlogId { get; set; }
[Required]
public string Url { get; set; }
}
Intercalaciones de columnas
Nota
Esta característica se incluyó por primera vez en EF Core 5.0.
Se puede definir una intercalación en columnas de texto, determinando cómo se comparan y ordenan. Por ejemplo, el siguiente fragmento de código configura una SQL Server que no tenga en cuenta mayúsculas de minúsculas:
modelBuilder.Entity<Customer>().Property(c => c.Name)
.UseCollation("SQL_Latin1_General_CP1_CI_AS");
Si todas las columnas de una base de datos necesitan usar una intercalación determinada, defina la intercalación en el nivel de base de datos en su lugar.
Puede encontrar información general EF Core compatibilidad con intercalaciones en la página de documentación de intercalación.
Comentarios de columna
Puede establecer un comentario de texto arbitrario que se establece en la columna de base de datos, lo que le permite documentar el esquema en la base de datos:
Nota
El establecimiento de comentarios a través de anotaciones de datos se introdujo en EF Core 5.0.
public class Blog
{
public int BlogId { get; set; }
[Comment("The URL of the blog")]
public string Url { get; set; }
}
Orden de las columnas
Nota
Esta característica se introdujo en EF Core 6.0.
De forma predeterminada, al crear una tabla con migraciones ,EF Core ordena primero las columnas de clave principal, seguidas de las propiedades del tipo de entidad y los tipos de propiedad y, por último, las propiedades de los tipos base. Sin embargo, puede especificar un orden de columna diferente:
public class EntityBase
{
[Column(Order = 0)]
public int Id { get; set; }
}
public class PersonBase : EntityBase
{
[Column(Order = 1)]
public string FirstName { get; set; }
[Column(Order = 2)]
public string LastName { get; set; }
}
public class Employee : PersonBase
{
public string Department { get; set; }
public decimal AnnualSalary { get; set; }
}
La API Fluent se puede usar para invalidar la ordenación realizada con atributos, incluida la resolución de conflictos cuando los atributos de propiedades diferentes especifican el mismo número de pedido.
Tenga en cuenta que, en el caso general, la mayoría de las bases de datos solo admiten columnas de ordenación cuando se crea la tabla. Esto significa que el atributo de orden de columna no se puede usar para volver a ordenar las columnas de una tabla existente.