EF Core - Criando entidades sem chaves
 Hoje veremos como podemos criar e trabalhar com entidades sem chaves usando o EF Core.

Às vezes, podemos precisar declarar entidades usando o EF Core que não possuem chaves primárias. Neste artigo, vamos entender por que tais entidades seriam necessárias e como defini-las.



Quando qualquer modelo do EF core é definido, por padrão, o EF core marca uma propriedade como chave primária. Uma propriedade pode ser declarada como chave primária decorando-a com o atributo [Key] ou via Fluent API usando o método HasKey.

Se não for especificado explicitamente, o EF Core verifica se existe uma propriedade com o nome “Id” ou {EntityName}Id, e, se houver tal propriedade, ela será marcada por padrão como chave primária para a entidade.

Se não houver tal propriedade, o EF core lançará um erro do tipo:
O tipo de entidade '{EntityName}' requer que uma chave primária seja definida. Se você pretendia usar um tipo de entidade sem chave, chame ‘HasNoKey’ em ‘OnModelCreating’.

O erro está pedindo para definir uma chave primária no modelo.

Mas e se não quisermos ?

Como conseguir isso ? 

Bem, a resposta está na própria mensagem de erro. Mas antes de analisar a sintaxe, vamos primeiro ver onde as entidades sem chave seriam necessárias.

Por que você precisaria de uma entidade sem chave primária ?

Entidades sem chave podem ser necessárias se o esquema do banco de dados contiver uma tabela ou View sem nenhuma chave primária.

Nesses casos, essa tabela ou View pode ser mapeada para uma entidade sem chave. Às vezes, entidades sem chave também podem ser usadas para mapear resultados de um SQL bruto.

Como podemos definir isso ?

Existem duas maneiras de definir uma entidade sem chave :

  1. Usar anotação de dados [Keyless] e decorar um modelo com este atributo;
  2. Usar a API fluente com o método HasNoKey para definir a entidade sem chave;

Quando uma entidade é definida como entidade sem chave, ela não pode conter uma chave primária. Portanto, nunca pode ser uma entidade principal, pois não possui uma chave. Além disso, as entidades sem chave não são rastreadas pelo DbContext.

O trecho de código abaixo mostra como usar o atributo DataAnnotation [Keyless] para marcar uma entidade "Aluno" como sem chave.

using Microsoft.EntityFrameworkCore;

 [Keyless]
public class Aluno
{
   public string? Nome { get; set; }

    public string? Email { get; set; }

    public string? Telefone { get; set; }

    public DateTime? Nascimento { get; set; }
}

A seguir a mesma entidade sendo definida com sem chave usando a API fluente :

public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> opt): base(opt)
    {}
    public DbSet<Product>? Products { get; set; }
    public DbSet<Aluno>? Alunos { get; set; }

       protected override void OnModelCreating(ModelBuilder modelBuilder)
       {
           modelBuilder.Entity<Aluno>()
                .HasNoKey();
       }      

}

Uma as formas de usar uma entidade sem chave em consultas é usar o método DbSet<T>.FromSqlInterpolated() e escrever uma consulta SQL que selecione as colunas da entidade sem chave.

Para uma entidade Products com Name, Amount podemos definir a consulta:

var products = context.Set<Products>()
    .FromSqlInterpolated($"SELECT TOP 10 Name, SUM(Amount) as Total
    FROM Products GROUP BY Name ORDER BY Total DESC")
    .ToList();

Características das entidades 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 armazenamentos 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, eles são diferentes dos tipos de entidade regulares, da seguinte forma:

No entanto podemos usar essas entidades nos seguintes contextos:

Nota:  Para mapear uma entidade sem chave para um objeto de banco de dados usando a Fluent API usamos os métodos ToTable e ToView.

"Estejam vigilantes, mantenham-se firmes na fé, sejam homens de coragem, sejam fortes."
1 Coríntios 16:13

Referências:


José Carlos Macoratti