Gestione della Persistenza dei Dati
In questa sezione imparerai come Lino configura Entity Framework Core affinché lo strato di dominio rimanga completamente isolato e i processi di migrazione del database siano prevedibili e controllati — sia in un servizio tradizionale (monolitico) sia in un servizio modulare.
Quando si crea un servizio tramite il comando lino new service, la CLI richiede due decisioni essenziali:
- Architettura — servizio tradizionale o modulare.
- Provider dati —
SqlServeroPostgreSql(altri provider saranno aggiunti nelle versioni future).
Nei servizi tradizionali (monoliti) o modulari (monoliti modulari), il database è unico per servizio. Tuttavia, nei servizi modulari, ogni modulo è mappato in uno schema distinto all’interno dello stesso database. Questo permette a ogni bounded context di mantenere uno spazio dei nomi logico separato, garantendo isolamento funzionale, versionamento indipendente e migrazioni più organizzate e sicure.
Configurazioni dei tipi di entità
Lino segue il principio Persistence‑Ignorant: le entità di dominio non conoscono i dettagli dell'infrastruttura.
Per questo motivo, tutto il mapping ORM è spostato in classi che implementano IEntityTypeConfiguration<T>, situate in Configurations/<EntityName>Configuration.cs.
- Ogni entità ha un file di configurazione dedicato.
- Convenzioni globali (es.:
decimal(18,2), collazione,DateTimecomeutc) possono essere centralizzate inModelConfiguration. - Le configurazioni vengono applicate nel
OnModelCreatingdiDbContexttramitemodelBuilder.ApplyConfigurationsFromAssembly(...).
DbContexts
Il DbContext rappresenta l'unità di transazione dell'applicazione. Lino genera automaticamente:
- Servizio tradizionale — un unico
AppDbContextcontenente tutti iDbSet<TEntity>. - Servizio modulare — un
<Module>DbContextper ogni bounded context. Così ogni modulo compila più velocemente, ha cicli di migrazione più brevi e riduce il rischio di merge conflicts.
Tutti i DbContext sono registrati in <Module>/Infrastructure.Persistence, esposti tramite IUnitOfWork e risolti tramite dependency injection.
Repository
I repository concreti si trovano in <Module>/Infrastructure.Persistence.Repositories e implementano le interfacce definite nel namespace <Module>/Domain.Repositories.
Ogni repository:
- Incapsula query complesse (LINQ,
FromSql, proiezioni DTO). - Espone solo i metodi necessari al dominio (centrato su Aggregate Root).
Unità di Lavoro (Unit of Work)
La Unità di Lavoro agisce come un confine transazionale che coordina molteplici repository, garantendo che tutte le operazioni vengano eseguite in modo atomico.
In scenari semplici, spesso è sufficiente il DbContext stesso. Tuttavia, Lino genera un'implementazione dedicata (UnitOfWork) che offre maggiore controllo e flessibilità.
- Consente il controllo manuale delle transazioni tramite
BeginTransaction,CommiteRollback, quando necessario. - Pubblica eventi di dominio durante la transazione corrente, assicurando che vengano eseguiti all'interno dello stesso ciclo di
commit. - Persiste eventi di integrazione nell’outbox, seguendo il Transaction Outbox Pattern, garantendo una consegna affidabile negli scenari di architettura distribuita (quando applicabile).
Gestione delle migrazioni
Lino semplifica e automatizza completamente il processo di Database Migrations con Entity Framework Core, eliminando compiti ripetitivi e rischi comuni di incoerenza. Per creare una nuova migrazione, esegui il seguente comando:
lino database migrations add
Quando esegui il comando, un assistente interattivo ti chiederà le seguenti informazioni:
- Servizio — Nome del progetto in cui verrà applicata la migrazione.
- Modulo — (solo nei servizi modulari) modulo a cui appartiene la modifica.
-
Nome della Migrazione — Inserisci una descrizione della modifica (es.:
AddCustomerIsActive). Lino gestirà automaticamente la versione corrente e l’ordine incrementale durante la generazione dello script.sql, seguendo questo modello:/Scripts/v1.2.3/001_AddCustomerIsActive.sql.
.cs generati da Entity Framework, Lino crea automaticamente anche lo script .sql corrispondente con le istruzioni DDL.
Questo facilita l’esecuzione manuale delle modifiche o la revisione da parte dei team di infrastruttura e DBA.
