Gerenciando Persistência de Dados
Nesta seção você aprenderá como o Lino configura o Entity Framework Core para que a camada de domínio permaneça totalmente isolada e os processos de migração de banco de dados sejam previsíveis e controlados — seja em um serviço tradicional (monolítico) ou em um serviço modular.
Ao criar um serviço através do comando lino new service, a CLI solicita duas decisões essenciais:
- Arquitetura — Serviço tradicional ou modular.
- Provedor de dados —
SqlServer
ouPostgreSql
(outros provedores serão adicionados em versões futuras).
Em serviços tradicionais (monólitos) ou modulares (monólitos modulares), o banco de dados é único por serviço. No entanto, em serviços modulares, cada módulo é mapeado em um schema distinto dentro do mesmo banco. Isso permite que cada bounded context mantenha um namespace lógico separado, garantindo isolamento funcional, versionamento independente e migrações mais organizadas e seguras.
Entity Type Configurations
O Lino segue o princípio Persistence‑Ignorant: as entidades de domínio não conhecem detalhes de infraestrutura.
Para isso, todo o mapeamento ORM é deslocado para classes que implementam IEntityTypeConfiguration<T>
, localizadas em Configurations/<EntityName>Configuration.cs
.
- Cada entidade possui um arquivo de configuração dedicado.
- Convenções globais (ex.:
decimal(18,2)
, collation,DateTime
comoutc
) podem ser centralizadas emModelConfiguration
. - Configurações são aplicadas no
OnModelCreating
doDbContext
viamodelBuilder.ApplyConfigurationsFromAssembly(...)
.
DbContexts
O DbContext
representa a unidade de transação da aplicação. O Lino gera automaticamente:
- Serviço tradicional — um único
AppDbContext
contendo todos osDbSet<TEntity>
. - Serviço modular — um
<Module>DbContext
por bounded context. Assim cada módulo compila mais rápido, possui ciclos de migração menores e reduz o risco de merge conflicts.
Todos os DbContext
são registrados em <Module>/Infrastructure.Persistence
, expostos via IUnitOfWork
e resolvidos por dependency injection
.
Repositórios
Repositórios concretos ficam em <Module>/Infrastructure.Persistence.Repositories
e implementam as interfaces definidas no namespace <Module>/Domain.Repositories
.
Cada repositório:
- Encapsula consultas complexas (LINQ,
FromSql
, projeções DTO). - Expõe apenas métodos necessários ao domínio (Aggregate Root‑centric).
Unit of Work
A Unit of Work atua como uma fronteira transacional que coordena múltiplos repositórios, garantindo que todas as operações sejam executadas de forma atômica.
Em cenários simples, o próprio DbContext
costuma ser suficiente. No entanto, o Lino gera uma implementação dedicada (UnitOfWork
) que oferece maior controle e flexibilidade.
- Permitir o controle manual de transações via
BeginTransaction
,Commit
eRollback
, quando necessário. - Publicar eventos de domínio durante a transação atual, garantindo que eles ocorram dentro do mesmo ciclo de
commit
. - Persistir eventos de integração no outbox, seguindo o Transaction Outbox Pattern, assegurando entrega confiável em cenários de arquitetura distribuída (quando aplicável).
Gerenciando Migrations
O Lino simplifica e automatiza completamente o processo de Database Migrations com o Entity Framework Core, eliminando tarefas repetitivas e riscos comuns de inconsistência. Para criar uma nova migração, execute o seguinte comando:
lino database migrations add
Ao rodar o comando, um assistente interativo solicitará as seguintes informações:
- Serviço — Nome do projeto onde a migração será aplicada.
- Módulo — (somente em serviços modulares) módulo ao qual a alteração pertence.
-
Nome da Migração — Informe a descrição da alteração (ex.:
AddCustomerIsActive
). O Lino cuidará automaticamente da versão atual e da ordenação incremental ao gerar o script.sql
, seguindo o padrão:/Scripts/v1.2.3/001_AddCustomerIsActive.sql
.
.cs
gerados pelo Entity Framework, o Lino também cria automaticamente o script .sql
correspondente com as instruções DDL.
Isso facilita a execução manual das mudanças ou a revisão por equipes de infraestrutura e DBAs.