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 —
SqlServer
oPostgreSql
(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,DateTime
comeutc
) possono essere centralizzate inModelConfiguration
. - Le configurazioni vengono applicate nel
OnModelCreating
diDbContext
tramitemodelBuilder.ApplyConfigurationsFromAssembly(...)
.
DbContexts
Il DbContext
rappresenta l'unitĂ di transazione dell'applicazione. Lino genera automaticamente:
- Servizio tradizionale — un unico
AppDbContext
contenente tutti iDbSet<TEntity>
. - Servizio modulare — un
<Module>DbContext
per 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
,Commit
eRollback
, 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.