Gestionando la Persistencia de Datos
En esta sección aprenderás cómo Lino configura Entity Framework Core para que la capa de dominio permanezca totalmente aislada y los procesos de migración de base de datos sean predecibles y controlados — ya sea en un servicio tradicional (monolítico) o en un servicio modular.
Al crear un servicio mediante el comando lino new service, la CLI solicita dos decisiones esenciales:
- Arquitectura — Servicio tradicional o modular.
- Proveedor de datos —
SqlServer
oPostgreSql
(otros proveedores se añadirán en futuras versiones).
En servicios tradicionales (monolitos) o modulares (monolitos modulares), la base de datos es única por servicio. Sin embargo, en servicios modulares, cada módulo se mapea en un esquema distinto dentro de la misma base de datos. Esto permite que cada bounded context mantenga un espacio de nombres lógico separado, garantizando aislamiento funcional, versionado independiente y migraciones más organizadas y seguras.
Configuraciones de tipo de entidad
Lino sigue el principio Persistence‑Ignorant: las entidades de dominio no conocen detalles de infraestructura.
Para ello, todo el mapeo ORM se desplaza a clases que implementan IEntityTypeConfiguration<T>
, ubicadas en Configurations/<EntityName>Configuration.cs
.
- Cada entidad tiene un archivo de configuración dedicado.
- Las convenciones globales (p. ej.,
decimal(18,2)
, collation,DateTime
comoutc
) pueden centralizarse enModelConfiguration
. - Las configuraciones se aplican en el
OnModelCreating
delDbContext
mediantemodelBuilder.ApplyConfigurationsFromAssembly(...)
.
DbContexts
El DbContext
representa la unidad de transacción de la aplicación. Lino genera automáticamente:
- Servicio tradicional — un único
AppDbContext
que contiene todos losDbSet<TEntity>
. - Servicio modular — un
<Module>DbContext
por cada bounded context. Así, cada módulo compila más rápido, tiene ciclos de migración más cortos y reduce el riesgo de conflictos de fusión.
Todos los DbContext
se registran en <Module>/Infrastructure.Persistence
, se exponen mediante IUnitOfWork
y se resuelven mediante dependency injection
.
Repositorios
Los repositorios concretos se encuentran en <Module>/Infrastructure.Persistence.Repositories
y implementan las interfaces definidas en el espacio de nombres <Module>/Domain.Repositories
.
Cada repositorio:
- Encapsula consultas complejas (LINQ,
FromSql
, proyecciones DTO). - Expone solo los métodos necesarios para el dominio (centrado en Aggregate Root).
Unidad de Trabajo (Unit of Work)
La Unidad de Trabajo actúa como una frontera transaccional que coordina múltiples repositorios, garantizando que todas las operaciones se ejecuten de forma atómica.
En escenarios simples, el propio DbContext
suele ser suficiente. Sin embargo, Lino genera una implementación dedicada (UnitOfWork
) que ofrece mayor control y flexibilidad.
- Permite el control manual de transacciones mediante
BeginTransaction
,Commit
yRollback
, cuando sea necesario. - Publica eventos de dominio durante la transacción actual, garantizando que ocurran dentro del mismo ciclo de
commit
. - Persiste eventos de integración en la outbox, siguiendo el Transaction Outbox Pattern, asegurando una entrega confiable en escenarios de arquitectura distribuida (cuando aplique).
Gestión de migraciones
Lino simplifica y automatiza completamente el proceso de Migraciones de Base de Datos con Entity Framework Core, eliminando tareas repetitivas y riesgos comunes de inconsistencia. Para crear una nueva migración, ejecuta el siguiente comando:
lino database migrations add
Al ejecutar el comando, un asistente interactivo solicitará la siguiente información:
- Servicio — Nombre del proyecto donde se aplicará la migración.
- Módulo — (solo en servicios modulares) módulo al que pertenece el cambio.
-
Nombre de la Migración — Indica una descripción del cambio (ej.:
AddCustomerIsActive
). Lino gestionará automáticamente la versión actual y el orden incremental al generar el script.sql
, siguiendo el patrón:/Scripts/v1.2.3/001_AddCustomerIsActive.sql
.
.cs
generados por Entity Framework, Lino también crea automáticamente el script .sql
correspondiente con las instrucciones DDL.
Esto facilita la ejecución manual de los cambios o la revisión por parte de los equipos de infraestructura y DBA.