O mapeamento de classes no .NET é o processo de associar classes da aplicação a tabelas no banco de dados ou a outros modelos de dados. O conceito de mapeamento vai muito além do banco de dados, ele pode aparecer em diversas áreas como: serialização de dados (JSON, XML), tranformação de dados para APIs (DTOs, ViewModels), etc. Isso pode ser feito de várias formas, dependendo da tecnologia utilizada, como Entity Framework Core, Dapper, AutoMapper, entre outros.

Mapeamento de classes

No EF Core, se você definir uma classe como abaixo:

public class Restaurante
{
    public int Id { get; set; }
    public string Nome { get; set; }
    public string Endereco { get; set; }
}

E adicioná-la ao seu DbContext:

public class AppDbContext : DbContext
{
    public DbSet<Restaurante> Restaurantes { get; set; }
}

O EF Core automaticamente cria uma tabela chamada Restaurantes com colunas baseadas nas propriedades da classe e você será capaz de rodar a migração para o seu banco deados, portanto, há riscos quando não se aplica os conceitos fundamentais para o mapeamento de classes

Mapeamento de Propriedades

O mapeamento de propriedades define características específicas de cada propriedade dentro de uma entidade. Aqui, configuramos detalhes como tamanho, tipo de dado, obrigatoriedade, valores padrão e chaves primárias.

Por que é importante? Quando não mapeamos nosssas propriedades, o EF Core utiliza o usa valores padrão durante a migração, que podem causar problemas de perfomance e estrutura do banco.

Mapeamento de Colunas

O mapeamento de coluna permite configurar como as propriedades e entidades serão nomeadas e estruturadas no banco de dados

Porque é importante? Sem esse mapeamento, o EF Core usaria o nome da propriedade como nome da coluna no banco, o que pode não seguir os padrões da equipe de DBAs ou dificultar a leitura dos dados.

Configuração de Modelagem

A configuração de modelagem é um conceito mais amplo e complexo. Envolve aspectos do mapeamento de entidades e conceitos mais profuindos de bancos de dados como:

Data Annotation vs. FluentAPI

Tanto Data Annotations quanto FluentAPI permitem aplicar esses três conceitos de mapeamento de classes. Porém, cada um tem suas particularidades. A escolha depende do nível de personalização que você deseja.

De forma geral, vou dar uma breve resumida dos objetivos e comparações, você pode se aprofundar se quiser no material posterior sobre Data Annotations e FluentAPI

Resumão

Critério Data Annotations Fluent API
Melhor para Configurações básicas Configurações avançadas e personalizadas
Organização Mistura regras no model, poluindo classes com atributos Separa configuração do modelo, mantendo a entidade limpa
Simplicidade Mais fácil de aplicar e melhor opção para projetos pequenos Pode ser verboso e precisa configurar no onModelCreating
Relacionamentos ❌ Suporte limitado ✔ Melhor para relações complexas
Configuração avançada ❌ Limitado ✔ Suporte total

Se o projeto é pequeno e simples, Data Annotations pode ser suficiente.

Se o projeto é grande ou requer configurações complexas, FluentAPI é a melhor escolha.

Data Annotation

Exemplo usando Data Annotation

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

public class Restaurante
{
    [Key] // Define a chave primária
    public int Id { get; set; }

    [Required] // Define como obrigatório
    [MaxLength(100)] // Limita o tamanho do campo
    public string Nome { get; set; }

    [Column(TypeName = "decimal(10,2)")] // Define tipo específico no banco
    public decimal Faturamento { get; set; }
}

Quando usar?

Fluent API

Exemplo usando Fluent API

public class RestauranteConfiguration : IEntityTypeConfiguration<Restaurante>
{
    public void Configure(EntityTypeBuilder<Restaurante> builder)
    {
        builder.HasKey(r => r.Id); // Define a chave primária

        builder.Property(r => r.Nome)
               .IsRequired()
               .HasMaxLength(100); // Define obrigatoriedade e tamanho máximo

        builder.Property(r => r.Faturamento)
               .HasColumnType("decimal(10,2)"); // Define o tipo no banco
    }

E depois, no DbContext:

public class MeuDbContext : DbContext
{
    public DbSet<Restaurante> Restaurantes { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.ApplyConfiguration(new RestauranteConfiguration());
    }
}

Quando usar?

Data Annotation

FluentAPI