This content originally appeared on DEV Community and was authored by Yuri Peixinho
Conceito
Ao trabalhar com Code First, existem convenções que são feitas no EF. Mas, as vezes você pode desejar não seguir as convenções e fazer algo diferente. As duas maneiras são usando Annotations e FluentAPI.
Alguns exemplos de convenções são:
- Chave Primária: Propriedades chamadas
ID
ou<NomeDaClasse>Id
**são automaticamente configuradas como chaves primárias - Colunas: O EF Core cria colunas para todas as propriedades de uma classe de entidade com o mesmo nome da propriedade por padrão.
Mas, há cenários de mapeamento em que não podem ser alcançados usando Annotations. Por isso o FluentAPI é considerado um recurso mais avançado que o Data Annotations e vale ressaltar que ele usa o mesmo namespace ystem.ComponentModel.DataAnnotations
.
As diferenças são nas abordagens, uma vez que a decoração por atributos (Data Annotations) atua sobre classes que representam Models
e suas propriedades, enquanto o FluentAPI atua em um nível global, enunciando as regras diretamente no contexto da aplicação. **
Quando usar FluentAPI?
Podemos considerar utilizar o Fluent em cenários mais específicos, onde requer um controle mais fino sobre o mapeamento entre as entidades e o banco de dados. Geralmente é mais vantajoso em aplicações de grande porte ou de alta complexidade, onde as necessidades específicas de configuração vão além do que as Data Anotations podem oferecer.
- Em projetos onde o controle detalhado do mapeamento de entidades é essencial.
- Em sistemas com requisitos complexos de relacionamento, desempenho, conformidade ou personalização.
- Em aplicações empresariais que precisam de configurações avançadas de banco de dados e otimização.
Exemplos de aplicações
- Aplicações Empresariais Complexas: onde múltiplas entidades possuem modelos complexos e com um alto nível de inter-relacionamento e heranças. Pode ser necessário para configurar de forma detalhada índices compostos, heranças, propriedade sombreada, validações específicas etc. Tudo isso de forma centralizada e mantidas de forma coesa.
- Migrações de Sistemas Legados: Quando migramos uma aplicação legada para o EF Core, onde o schema do banco de dados existente deve ser mapeado cuidadosamente para novas classes de domínio.
- Aplicações com Processo de Negócios Personalizados: Sistemas que têm regras de negócios altamente personalizados, como plataforma de seguros, sistemas de planejamento de recursos empresariais (ERP) ou plataforma de gerenciamento de projeto complexo.
- Soluções Saas Personalizáveis: Software como serviço, onde os clientes exigem personalizações significativas em termos de estruturas de dados e comportamento do sistema. Por permitir a criação de dados flexível, diferentes clientes podem ter configurações diferentes, mas ainda assim, serem gerados de uma única base de código.
Além disso, há vários outros fatores não citados como: projeto de pesquisa e desenvolvimento, plataformas multitenancy ou multibanco, aplicações que precisam de alto desempenho.
ModelBuilder
No Entity Framework, a classe ModelBuilder atua como uma Fluent API. Usando essa classe, podemos configurar várias coisas diferentes.
O Entity Framework Core Fluent API configura os seguintes aspectos de um Model
:
Configuração do Model
Configura o mapeamento do Model
dos bancos de dados. Configura Schema padrão, funções do banco de dados, atributos adicionais de Data Annotation e entidades a serem excluídas do mapeamento.
Configuração da Entidade
Configura as tabelas da entidades e mapea os relacionamentos. PrimaryKey, AlternateKey, Index, table name, one-to-one, one-to-many, many-to-many relationships etc.
Configuração de Propriedade
Configura as propriedades do mapeamento da coluna. name, default value, nullability, Foreignkey, data type, concurrency column etc.
Podemos dizer que o FluentAPI é particulamente útil quando precisamos personalizar configurações que vão além das anotações de atributos nas classes, como por exemplo:
- Configurações avançadas de relacionamentos
- Configurações não suportadas por Data Annotation
- Configurações globais e reutilizáveis
- Definição de tipos de propriedade
- Validações complexas
Atributos
Os atributos servem para definir regras de validação, requisitos colunas de banco de dados (como tamanho de campo obrigatoriedade) e configurações de mapeamentos diretamente nas propriedades da classe de modelo.
Existem diversos atributos que pode ser adicionado em sua aplicação. Quanto mais você utilizar o Data Annotation, mais naturalmente você será capaz de conhecer e saber quais os tipos de atributos existentes. Vale ressaltar que você pode combinar múltiplos atributos em uma propriedade.
Atributos — Data Annotations vs. Fluent API
Data Annotations anotações são diretamente aplicadas às propriedades do modelo e são refletidas na estrutura da tabela do banco de dados quando as migrações são aplicadas. Elas são simples e diretas, mas podem se tornar difíceis de gerenciar em modelos complexos.
Fluent API oferece mais flexibilidade e centralização das configurações de mapeamento em um único local. É mais adequado para cenários complexos e para projetos em que você precisa de uma configuração mais refinada, como relacionamentos entre entidades ou configurações específicas do banco de dados.
Agora, para exemplificar vamos comparar dois exemplos para o mapeamento de um modelo Telefone
usando as duas abordagens e como elas serão refletidas no banco de dados:
1. Mapeamento usando Data Annotations
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
public class Telefone
{
[Key]
public int Id { get; set; }
[Required]
[StringLength(3, ErrorMessage = "O DDD deve conter 3 caracteres.")]
public string DDD { get; set; }
[Required]
[MaxLength(9, ErrorMessage = "O número do telefone deve ter no máximo 9 caracteres.")]
public string Numero { get; set; }
public int TipoTelefoneID { get; set; }
public int RestauranteID { get; set; }
public TelefoneTipo TelefoneTipo { get; set; }
public Restaurante Restaurante { get; set; }
}
Reflexo no Banco de Dados SQL:
Id: INT (chave primária)
DDD: VARCHAR(3), obrigatório
Numero: VARCHAR(9), obrigatório
TipoTelefoneID: INT.
RestauranteID: INT.
2. Mapeamento usando Fluent API
Modelo:
public class Telefone
{
public int Id { get; set; }
public string DDD { get; set; }
public string Numero { get; set; }
public int TipoTelefoneID { get; set; }
public int RestauranteID { get; set; }
public TelefoneTipo TelefoneTipo { get; set; }
public Restaurante Restaurante { get; set; }
}
Contexto com Fluent API:
using Microsoft.EntityFrameworkCore;
public class AppDbContext : DbContext
{
public DbSet<Telefone> Telefones { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Telefone>()
.HasKey(t => t.Id);
modelBuilder.Entity<Telefone>()
.Property(t => t.DDD)
.IsRequired()
.HasMaxLength(3)
.HasColumnName("DDD");
modelBuilder.Entity<Telefone>()
.Property(t => t.Numero)
.IsRequired()
.HasMaxLength(9)
.HasColumnName("Numero");
modelBuilder.Entity<Telefone>()
.Property(t => t.TipoTelefoneID)
.HasColumnName("TipoTelefoneID");
modelBuilder.Entity<Telefone>()
.Property(t => t.RestauranteID)
.HasColumnName("RestauranteID");
}
}
Reflexo no Banco de Dados SQL:
Id: INT (chave primária)
DDD: VARCHAR(3), obrigatório
Numero: VARCHAR(9), obrigatório
TipoTelefoneID: INT.
RestauranteID: INT
This content originally appeared on DEV Community and was authored by Yuri Peixinho

Yuri Peixinho | Sciencx (2025-02-26T02:19:30+00:00) Fluent API. Retrieved from https://www.scien.cx/2025/02/26/fluent-api/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.