Tipos de entidad
Incluir un DbSet de un tipo en el contexto significa que se incluye en EF Core modelo de la aplicación. normalmente se hace referencia a un tipo como una entidad. EF Core leer y escribir instancias de entidad desde o hacia la base de datos y, si usa una base de datos relacional, EF Core puede crear tablas para las entidades a través de migraciones.
Inclusión de tipos en el modelo
Por convención, los tipos que se exponen en las propiedades de DbSet en el contexto se incluyen en el modelo como entidades. También se incluyen los tipos de entidad especificados en el método , al igual que los tipos que se encuentran explorando de forma recursiva las propiedades de navegación de otros tipos de OnModelCreating entidad detectados.
En el ejemplo de código siguiente, se incluyen todos los tipos:
Blogse incluye porque se expone en una propiedad DbSet en el contexto.Postse incluye porque se detecta a través de laBlog.Postspropiedad de navegación .AuditEntryporque se especifica enOnModelCreating.
internal class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<AuditEntry>();
}
}
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 Blog Blog { get; set; }
}
public class AuditEntry
{
public int AuditEntryId { get; set; }
public string Username { get; set; }
public string Action { get; set; }
}
Exclusión de tipos del modelo
Si no desea incluir un tipo en el modelo, puede excluirlo:
[NotMapped]
public class BlogMetadata
{
public DateTime LoadedFromDatabase { get; set; }
}
Exclusión de migraciones
Nota
La capacidad de excluir tablas de las migraciones se introdujo en EF Core 5.0.
A veces resulta útil tener el mismo tipo de entidad asignado en varios DbContext tipos. Esto es especialmente cierto cuando se usan contextos delimitados, para los que es habitual tener un tipo diferente para cada contexto enlazado.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<IdentityUser>()
.ToTable("AspNetUsers", t => t.ExcludeFromMigrations());
}
Con esta configuración, las migraciones no crearán la tabla, pero todavía se incluyen en el modelo y AspNetUsers se pueden usar con IdentityUser normalidad.
Si necesita empezar a administrar la tabla de nuevo mediante migraciones, se debe crear una nueva migración donde AspNetUsers no se excluya. La siguiente migración contendrá ahora los cambios realizados en la tabla.
Nombre de la tabla
Por convención, cada tipo de entidad se configurará para asignarse a una tabla de base de datos con el mismo nombre que la propiedad DbSet que expone la entidad. Si no existe DbSet para la entidad determinada, se usa el nombre de clase.
Puede configurar manualmente el nombre de la tabla:
[Table("blogs")]
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
Esquema de tabla
Cuando se usa una base de datos relacional, las tablas se crean por convención en el esquema predeterminado de la base de datos. Por ejemplo, Microsoft SQL Server usará el dbo esquema (SQLite no admite esquemas).
Puede configurar las tablas que se crearán en un esquema específico como se muestra a continuación:
[Table("blogs", Schema = "blogging")]
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
En lugar de especificar el esquema para cada tabla, también puede definir el esquema predeterminado en el nivel de modelo con la API fluida:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("blogging");
}
Tenga en cuenta que establecer el esquema predeterminado también afectará a otros objetos de base de datos, como secuencias.
Visualización de la asignación
Los tipos de entidad se pueden asignar a vistas de base de datos mediante Fluent API.
Nota
EF asumirá que la vista a la que se hace referencia ya existe en la base de datos, no la creará automáticamente en una migración.
modelBuilder.Entity<Blog>()
.ToView("blogsView", schema: "blogging");
La asignación a una vista quitará la asignación de tabla predeterminada, pero a partir de EF 5.0, el tipo de entidad también se puede asignar a una tabla explícitamente. En este caso, la asignación de consultas se usará para las consultas y la asignación de tabla se usará para las actualizaciones.
Sugerencia
Para probar los tipos de entidad asignados a vistas mediante el proveedor en memoria, así como asignarlos a una consulta a través de ToInMemoryQuery . Consulte un ejemplo que se puede ejecutar mediante esta técnica para obtener más detalles.
Asignación de funciones con valores de tabla
Es posible asignar un tipo de entidad a una función con valores de tabla (TVF) en lugar de a una tabla de la base de datos. Para ilustrar esto, vamos a definir otra entidad que represente el blog con varias entradas. En el ejemplo, la entidad no tiene clave,pero no tiene que serlo.
public class BlogWithMultiplePosts
{
public string Url { get; set; }
public int PostCount { get; set; }
}
A continuación, cree la siguiente función con valores de tabla en la base de datos, que devuelve solo blogs con varias entradas, así como el número de entradas asociadas a cada uno de estos blogs:
CREATE FUNCTION dbo.BlogsWithMultiplePosts()
RETURNS TABLE
AS
RETURN
(
SELECT b.Url, COUNT(p.BlogId) AS PostCount
FROM Blogs AS b
JOIN Posts AS p ON b.BlogId = p.BlogId
GROUP BY b.BlogId, b.Url
HAVING COUNT(p.BlogId) > 1
)
Ahora, la BlogWithMultiplePosts entidad se puede asignar a esta función de la siguiente manera:
modelBuilder.Entity<BlogWithMultiplePosts>().HasNoKey().ToFunction("BlogsWithMultiplePosts");
Nota
Para asignar una entidad a una función con valores de tabla, la función debe ser sin parámetros.
Convencionalmente, las propiedades de entidad se asignarán a columnas que coincidan devueltas por tvf. Si las columnas devueltas por la TVF tienen nombres diferentes a la propiedad de entidad, las columnas de la entidad se pueden configurar mediante el método , al igual que cuando se asigna a una HasColumnName tabla normal.
Cuando el tipo de entidad se asigna a una función con valores de tabla, la consulta:
var query = from b in context.Set<BlogWithMultiplePosts>()
where b.PostCount > 3
select new { b.Url, b.PostCount };
Produce el siguiente SQL:
SELECT [b].[Url], [b].[PostCount]
FROM [dbo].[BlogsWithMultiplePosts]() AS [b]
WHERE [b].[PostCount] > 3
Comentarios de tabla
Puede establecer un comentario de texto arbitrario que se establece en la tabla 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 EF Core 5.0.
[Comment("Blogs managed on the website")]
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
Tipos de entidad de tipo compartido
Nota
La compatibilidad con tipos de entidad de tipo compartido se introdujo en EF Core 5.0.
Los tipos de entidad que usan el mismo tipo CLR se conocen como tipos de entidad de tipo compartido. Estos tipos de entidad deben configurarse con un nombre único, que se debe proporcionar siempre que se utilice el tipo de entidad de tipo compartido, además del tipo CLR. Esto significa que la propiedad DbSet correspondiente debe implementarse mediante una llamada a Set .
internal class MyContext : DbContext
{
public DbSet<Dictionary<string, object>> Blogs => Set<Dictionary<string, object>>("Blog");
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.SharedTypeEntity<Dictionary<string, object>>(
"Blog", bb =>
{
bb.Property<int>("BlogId");
bb.Property<string>("Url");
bb.Property<DateTime>("LastUpdated");
});
}
}