O Entity Framework Core oferece dois modos de trabalho principais para mapear entre o código C# e o banco de dados. A escolha entre eles impacta significativamente o fluxo de trabalho e a arquitetura do projeto.
Modo Code First
Neste modo, o desenvolvimento começa com a definição do modelo de domínio no código. O banco de dados é gerado ou atualizado a partir dessas classes.
Fluxo de Trabalho
Classes de Modelo → Configurações → Migrações → Banco de Dados
Exemplo de Código
// Definição da entidade
public class Item
{
public int Identifier { get; set; }
public string Description { get; set; }
public decimal UnitPrice { get; set; }
public DateTime RecordTimestamp { get; set; }
}
// Contexto do Banco de Dados
public class StoreContext : DbContext
{
public DbSet<Item> Catalog { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Item>()
.Property(i => i.Description)
.IsRequired()
.HasMaxLength(250);
}
}
// Comandos para gerar e aplicar migrações
// dotnet ef migrations add InitialSchema
// dotnet ef database update
Cenários de Aplicação
Novos Projetos
Quando o banco de dados ainda não existe, permite projetar o modelo de domínio livremente.
Desenvolvimento Ágil
Ideal quando os requisitos mudam frequentemente. Alterações na entidade levam diretamente a migrações no banco.
Projetos com Design Dirigido pelo Domínio (DDD)
Enfatiza o modelo de domínio como centro do desenvolvimento.
public class Venda : EntidadeRaiz
{
public ICollection<LinhaItem> Itens { get; private set; }
public void AdicionarItem(Item produto, int quantidade)
{
// Lógica de negócio e validações
}
}
Controle Total da Equipe
Equipes que podem modificar livremente o schema do banco de dados sem depender de outro departamento.
Vantagens
- Controle Total: A estrutura do banco é definida e versionada no código.
- Iteração Rápida: Ciclo curto entre modelagem e implementação no banco.
- Amigável para Versionamento: Migrações são arquivos de código que podem ser commitados no controle de versão.
Modo Database First
Este modo parte de um banco de dados existente para gerar as classes C# que representam seu schema.
Fluxo de Trabalho
Banco de Dados Existente → Engenharia Reversa → Classes de Entidade → Utilização
Uso Prático
# Gerar modelos a partir de um banco existente
dotnet ef dbcontext scaffold "Server=localhost;Database=SysLegacy;User=sa;Password=pass;" Microsoft.EntityFrameworkCore.SqlServer -o GeneratedModels
Cenários de Aplicação
Integração com Sistemas Legados
Essencial quando o aplicativo precisa trabalhar com um banco de dados pré-existente e complexo.
-- Schema legado com regras de negócio complexas em procedures
CREATE TABLE Clientes_Historico (
Cod_Cliente INT NOT NULL,
Dados_Historico XML,
CONSTRAINT PK_ClientesHistorico PRIMARY KEY (Cod_Cliente)
);
Organizações com Equipe de DBAs
Quando o banco de dados é projetado e otimizado por um time dedicado de especialistas em banco de dados.
Bancos de Dados Compartilhados
Para sistemas onde múltiplas aplicações utilizam o mesmo banco de dados, garantindo consistência estrutural.
Vantagens
- Reutiliza Investimentos: Aproveita o design, otimizações e investimentos já feitos no banco de dados.
- Menor Curva de Aprendizado: A estrutura do banco já é conhecida e validada.
- Compatibilidade: Mantém a integridade com outros sistemas que dependem do mesmo schema.
Comparativo Detalhado
| Aspecto | Code First | Database First |
|---|---|---|
| Ponto de Partida | Modelos de Domínio no Código | Banco de Dados Existente |
| Controle do Schema | Equipe de Desenvolvimento | Equipe de DBA / Administradores |
| Processo de Mudença | Código → Migração → Banco de Dados | Banco de Dados → Re-gerar Modelos |
| Versionamento | Arquivos de migração versionáveis | Apenas as classes geradas podem ser versionadas |
| Otimização do Banco | Responsabilidade da equipe de desenvolvimento | Normalmente já realizada pelo DBA |
| Refatoração | Alta flexibilidade (renomear, reestruturar) | Limitada à estrutura existente |
Abordagens Mistas e Casos Reais
Caso 1: Microserviços
Em uma arquitetura de microserviços, cada serviço tipicamente usa Code First, mantendo seu banco de dados isolado.
// Serviço de Pedidos
public class PedidosContext : DbContext
{
public DbSet<Pedido> Pedidos { get; set; }
}
// Serviço de Estoque
public class EstoqueContext : DbContext
{
public DbSet<ItemEstoque> Itens { get; set; }
}
Caso 2: Modernização de Sistemas Legados
Uma estratégia comum é usar Database First para as tabelas centrais legadas e Code First para novas funcionalidades.
public class ContextoHibrido : DbContext
{
// Entidades geradas a partir do banco legado
public DbSet<ClienteLegado> ClientesLegados { get; set; }
// Entidades criadas com Code First para novas features
public DbSet<FuncionalidadeNova> NovasFuncionalidades { get; set; }
}
Recomendações de Escolha
Opte por Code First quando:
- Iniciar um projeto verde (greenfield).
- Trabalhar com um pequeno time ou equipe full-stack.
- Precisar de alta flexibilidade para refatoração.
- Utilizar bancos de dados embutidos como SQLite para desenvolvimento.
Opte por Database First quando:
- Integrar-se a um sistema legado com um banco de dados complexo e consolidado.
- Operar em uma grande organização com governança de banco de dados rígida.
- O banco de dados já ter sido otimizado para performance por especialistas.
A tendência em desenvolvimento moderno favorece o Code First por sua agilidade e foco no código. Contudo, o Database First permanece uma ferramenta indispensável para cenários de integração e modernização de sistemas.