Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Observação
Esse recurso foi adicionado sob o nome dos tipos de consulta. Mais tarde, foi alterado o nome para tipos de entidade sem chave.
Além dos tipos de entidade regulares, um modelo EF Core pode conter tipos de entidade sem chave, que podem ser usados para realizar consultas de banco de dados em dados que não contêm valores de chave.
Definindo tipos de entidade sem chave
Os tipos de entidades sem chave podem ser definidos da seguinte forma:
[Keyless]
public class BlogPostsCount
{
public string BlogName { get; set; }
public int PostCount { get; set; }
}
Características dos tipos de entidade sem chave
Os tipos de entidade sem chave suportam muitos dos mesmos recursos de mapeamento que os tipos de entidade regulares, como mapeamento de herança e propriedades de navegação. Em repositórios relacionais, eles podem configurar os objetos e colunas do banco de dados de destino por meio de métodos de API fluentes ou anotações de dados.
No entanto, são diferentes dos tipos de entidades regulares na medida em que:
- Não é possível ter uma chave definida.
- Nunca são rastreados para alterações no DbContext e, portanto, nunca são inseridos, atualizados ou excluídos no banco de dados.
- Nunca são descobertos por convenção.
- Suporta apenas um subconjunto de capacidades de mapeamento de navegação, especificamente:
- Eles nunca podem agir como o fim principal de um relacionamento.
- Eles podem não ter caminhos para entidades próprias.
- Eles só podem conter propriedades de navegação de referência apontando para entidades regulares.
- As entidades não podem conter propriedades de navegação para tipos de entidade sem chave.
- Precisa ser configurada com uma anotação de dados
[Keyless]ou um método de chamada.HasNoKey(). - Pode ser mapeado para uma consulta definidora. Uma consulta definidora é uma consulta declarada no modelo que atua como uma fonte de dados para um tipo de entidade sem chave.
- Pode ter uma hierarquia, mas deve ser mapeada como TPH.
- Não é possível usar a divisão de tabela ou a divisão de entidade.
Cenários de utilização
Alguns dos principais cenários de uso para tipos de entidade sem chave são:
- Servindo como o tipo de retorno para consultas SQL.
- Mapeamento para exibições de banco de dados que não contêm uma chave primária.
- Mapeamento para tabelas que não têm uma chave primária definida.
- Mapeamento para consultas definidas no modelo.
Mapeamento de objetos de banco de dados
O mapeamento de um tipo de entidade sem chave para um objeto de base de dados é realizado usando a API fluent ToTable ou ToView. Do ponto de vista do EF Core, o objeto de base de dados especificado neste método é uma vista, o que significa que é considerado uma fonte de consulta apenas leitura e não pode ser o alvo de operações de atualização, inserção ou exclusão. No entanto, isso não significa que o objeto de banco de dados seja realmente necessário ser uma vista de base de dados. Como alternativa, pode ser uma tabela de banco de dados que será tratada como somente leitura. Por outro lado, para tipos de entidade regulares, o EF Core assume que um objeto de banco de dados especificado no método ToTable pode ser tratado como uma tabela, o que significa que ele pode ser usado como uma fonte de consulta, mas também pode ser alvo de operações de atualização, exclusão e inserção. Na verdade, você pode especificar o nome de uma exibição de banco de dados em ToTable e tudo deve funcionar bem, desde que a exibição esteja configurada para ser atualizável no banco de dados.
Exemplo
O exemplo a seguir mostra como usar tipos de entidade sem chave para consultar uma exibição de banco de dados.
Sugestão
Você pode visualizar a amostra do deste artigo no GitHub.
Primeiro, definimos um modelo simples de Blog e Post:
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public ICollection<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
}
Em seguida, definimos uma visualização de banco de dados simples que nos permitirá consultar o número de posts associados a cada blog:
await db.Database.ExecuteSqlRawAsync(
@"CREATE VIEW View_BlogPostCounts AS
SELECT b.Name, Count(p.PostId) as PostCount
FROM Blogs b
JOIN Posts p on p.BlogId = b.BlogId
GROUP BY b.Name");
Em seguida, definimos uma classe para armazenar o resultado da exibição do banco de dados:
public class BlogPostsCount
{
public string BlogName { get; set; }
public int PostCount { get; set; }
}
Em seguida, configuramos o tipo de entidade sem chave em OnModelCreating usando a HasNoKey API.
Usamos a API de configuração fluente para configurar o mapeamento para o tipo de entidade sem chave:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<BlogPostsCount>(
eb =>
{
eb.HasNoKey();
eb.ToView("View_BlogPostCounts");
eb.Property(v => v.BlogName).HasColumnName("Name");
});
}
Em seguida, configuramos o DbContext para incluir o DbSet<T>.
public DbSet<BlogPostsCount> BlogPostCounts { get; set; }
Finalmente, podemos consultar a visualização do banco de dados da maneira padrão:
var postCounts = await db.BlogPostCounts.ToListAsync();
foreach (var postCount in postCounts)
{
Console.WriteLine($"{postCount.BlogName} has {postCount.PostCount} posts.");
Console.WriteLine();
}
Sugestão
Nota que também definimos um atributo de consulta a nível de contexto (DbSet) para servir de raiz para consultas desse tipo.
Sugestão
Para testar tipos de entidade sem chave mapeados para exibições usando o provedor na memória, mapeie-os para uma consulta via ToInMemoryQuery. Consulte os documentos do provedor na memória para obter mais informações.