Con il rilascio di .NET 10, Microsoft ha reso disponibile Entity Framework Core 10 (EF10). Essendo una versione LTS (Long Term Support), EF10 non è solo un aggiornamento incrementale, ma si consolida come il pilastro per l’accesso ai dati nel prossimo triennio, portando con sé miglioramenti radicali nella gestione dei dati relazionali, documentali e vettoriali.
Vector Search: Oltre la fase sperimentale
La ricerca vettoriale, introdotta come sperimentale in EF9, raggiunge ora la piena maturità. EF10 permette di integrare nativamente funzionalità di AI e ricerca semantica.
- Supporto Nativo: Supporto stabile per tipi di dati vettoriali e indici di somiglianza.
- Nuove API di configurazione: Introduzione di
IsVectorPropertyeIsVectorIndexper definire i vettori nel modello tramite Fluent API. - RRF (Reciprocal Rank Fusion): Supporto alla ricerca ibrida (testuale + vettoriale) per risultati estremamente precisi.
Vector Similarity Search
Questa è la feature “killer” per chi lavora con l’Intelligenza Artificiale (RAG – Retrieval Augmented Generation). Supponiamo di avere un database di prodotti e di voler cercare quelli “semanticamente” simili a una descrizione testuale, usando degli embedding (vettori).
Configurazione del Modello:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public float[] Embedding { get; set; } // La proprietà vettoriale
}
// Nel DbContext
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>()
.Property(b => b.Embedding)
.IsVectorProperty(dimensions: 1536); // Novità EF10: API dedicata
}
Esecuzione della Query di ricerca:
// Il vettore generato dall'AI per la nostra ricerca (es. "Scarpe da corsa blu")
float[] searchVector = GetEmbeddingFromAI("Scarpe da corsa blu");
var similarProducts = await context.Products
.OrderBy(p => EF.Functions.VectorDistance(p.Embedding, searchVector))
.Take(5)
.Select(p => new { p.Name, Distance = EF.Functions.VectorDistance(p.Embedding, searchVector) })
.ToListAsync();
// EF10 genera il comando SQL specifico (es. <=> in pgvector o simili per SQL Server)
Perché è importante: In precedenza, integrare la ricerca vettoriale richiedeva spesso l’uso di SQL grezzo o librerie esterne non integrate nel Change Tracker di EF. Ora è tutto nativo, tipizzato e supporta le operazioni di ordinamento e filtraggio standard.
Rivoluzione JSON e SQL Server 2025
EF10 abbraccia il nuovo tipo di dato JSON nativo introdotto in SQL Server 2025 e Azure SQL.
- Mapping diretto: È ora possibile mappare tipi complessi direttamente in colonne JSON con il metodo
.ToJson(). - Update Efficienti: Grazie a
ExecuteUpdateAsync, EF10 può generare SQL ottimizzato per aggiornare singole proprietà all’interno di un documento JSON senza dover riscrivere l’intero blob. - Resilienza dello schema: Se un documento JSON non contiene una proprietà definita come “obbligatoria” nel modello C#, EF10 ora materializza un valore di default invece di lanciare un’eccezione, facilitando l’evoluzione dei dati.
LINQ: Potenza e Sintassi Semplificata
Il traduttore LINQ è stato potenziato per ridurre la necessità di scrivere SQL grezzo:
- LeftJoin e RightJoin: Finalmente introdotti come metodi nativi in LINQ, eliminando i complessi pattern basati su
SelectManyeDefaultIfEmpty. - Aggregazioni ottimizzate: Traduzione più efficiente di
Count()su collezioni e miglior gestione diMin/Maxsu set di dati filtrati conDistinct. - ExecuteUpdate con logica custom: Ora è possibile includere logica condizionale (lambda non-expression) all’interno di
ExecuteUpdateAsync, rendendo gli aggiornamenti massivi molto più flessibili.
Esempio di Join Nativi (LeftJoin)
Prima di EF Core 10, per eseguire un Left Join (per ottenere, ad esempio, tutti i Clienti anche se non hanno ordini), era necessario utilizzare una sintassi verbosa basata su GroupJoin e SelectMany.
Con EF10, la sintassi diventa lineare e intuitiva:
using var context = new MyDbContext();
// Recuperiamo tutti i clienti e i loro ordini (se presenti)
var query = context.Customers
.LeftJoin(
context.Orders,
customer => customer.Id, // Chiave esterna lato Customer
order => order.CustomerId, // Chiave esterna lato Order
(customer, order) => new // Risultato
{
CustomerName = customer.Name,
OrderId = (int?)order.Id, // L'ordine può essere null
OrderDate = (DateTime?)order.OrderDate
})
.ToList();
// EF10 traduce questo direttamente in un LEFT JOIN SQL pulito
Perché è importante: Il codice è molto più leggibile e riduce drasticamente gli errori comuni che si commettevano con il pattern DefaultIfEmpty().
Gestione Avanzata dei Filtri di Query
I Global Query Filters diventano nominativi e granulari. Mentre prima era una scelta “tutto o niente” (IgnoreQueryFilters), in EF10 è possibile definire più filtri per entità e disabilitarli singolarmente. Questo è un game-changer per applicazioni multi-tenant complesse o sistemi con logiche di soft-delete stratificate.
Performance e Manutenibilità
- Materializzazione dei parametri: I nomi dei parametri SQL generati sono ora più leggibili (es.
@cityinvece di@__city_0), facilitando il debugging. - Sicurezza dei Log: EF10 redige automaticamente i valori costanti in-line dai log SQL se la registrazione dei dati sensibili è disattivata, aumentando la conformità ai criteri di sicurezza.
- Miglioramenti per Azure Cosmos DB: Esperienza di migrazione e modellazione dei documenti notevolmente semplificata, con supporto nativo alla Full-Text Search.
Certamente. Ecco due esempi pratici che mostrano come queste nuove funzionalità semplifichino drasticamente il codice rispetto alle versioni precedenti di EF Core.
Breaking Changes da monitorare
Nonostante sia una versione stabile, ci sono alcuni punti di attenzione:
- Multi-targeting: Gli strumenti di EF ora richiedono l’esplicita indicazione del framework (
--framework) in progetti che puntano a più versioni di .NET. - Vincoli di Default: La prima migrazione generata con EF10 rinominerà i vincoli di default esistenti per allinearli alle nuove convenzioni di naming.
Entity Framework Core 10 trasforma l’ORM da semplice “mappatore di tabelle” a un vero e proprio motore di orchestrazione dati che gestisce con la stessa eleganza SQL, NoSQL e Vector Store. È il momento ideale per pianificare l’aggiornamento, specialmente per chi punta a sfruttare le potenzialità dell’Intelligenza Artificiale Generativa nelle proprie applicazioni.