Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Observação
Esse recurso foi adicionado sob o nome de tipos de consulta. Mais tarde, ele foi renomeado para tipos de entidade sem chave.
Além dos tipos de entidade regulares, um modelo do 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 entidade sem chave podem ser definidos da seguinte maneira:
[Keyless]
public class BlogPostsCount
{
public string BlogName { get; set; }
public int PostCount { get; set; }
}
Características de tipos de entidade sem chave
Tipos de entidade sem chave dão suporte a 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 de banco de dados de destino por meio de métodos de API fluentes ou anotações de dados.
No entanto, eles são diferentes dos tipos de entidade regulares em que:
- Não é possível ter uma chave definida.
- Nunca são controladas para alterações no DbContext e, portanto, nunca são inseridas, atualizadas ou excluídas no banco de dados.
- Nunca são descobertos por convenção.
- Dá suporte apenas a um subconjunto de recursos de mapeamento de navegação, especificamente:
- Eles podem nunca agir como o fim principal de um relacionamento.
- Eles podem não ter navegações para entidades possuídas.
- Elas 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 configurado com uma
[Keyless]anotação de dados ou uma.HasNoKey()chamada de método. - Pode ser mapeado para uma consulta de definição. Uma consulta que define é 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 divisão de tabela ou divisão de entidade.
Cenários de uso
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 para objetos de banco de dados
O mapeamento de um tipo de entidade sem chave para um objeto de banco de dados é realizado usando a ToTable ou ToView API fluente. Sob a perspectiva do EF Core, o objeto de banco de dados especificado neste método é uma visão, o que significa que ele é tratado como uma fonte de consulta somente leitura e não pode ser o destino 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 para ser uma visão de banco 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 pressupõe que um objeto de banco de dados especificado no método ToTable possa 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 ToTable de banco de dados 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.
Dica
Você pode exibir o exemplo deste artigo no GitHub.
Primeiro, definimos um modelo simples de Blog e Postagem:
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 exibição de banco de dados simples que nos permitirá consultar o número de postagens associadas 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 manter o resultado na 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; }
Por fim, podemos consultar a exibiçã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();
}
Dica
Observe que também definimos uma propriedade de consulta no nível de contexto (DbSet) para atuar como uma raiz para consultas deste tipo.
Dica
Para testar tipos de entidade sem chave mapeados para exibições usando o provedor em memória, mapeie-os para uma consulta por meio de ToInMemoryQuery. Consulte os documentos do provedor na memória para obter mais informações.