Uno dei task più ricorrenti quando si lavora con un Entity Framework è quello di dover recuperare una serie di entity a partire da una lista di id. Questo in LINQ si traduce nell'avere una variabile con la lista di id che all'interno del metodo Where viene usata insieme a Contains.
int[] ids = [1,2,3,4,5] var people = await ctx.People .Where(c => ids.Contains(c.Id)) .ToListAsync()
Sebbene questo codice sia perfettamente funzionante, la sua traduzione in SQL non è stata ottimale fino alla versione 7. Infatti fino a quella versione il codice veniva tradotto nel sequente codice SQL (semplificato).
SELECT * FROM People WHERE Id IN (1,2,3,4,5)
Come possiamo vedere, la lista di id è stampata nel codice SQL generato e quindi ogni volta che cambiano gli id, SQL Server genera un nuovo query plan e lo mette in cache causando potenziali problemi di performance perchè altre query vengono eliminate dalla cache.
Con la versione 8, per ovviare a questo problema, il team ha sfruttato le potenzialità di JSON e ha modificato il codice SQL generato nel seguente.
SELECT * FROM People WHERE Id IN ( SELECT value FROM OPENJSON(@__ids_0) WITH ([value] int '$') )
Come si vede, la clausola IN non contiene più la lista di valori da cercare. Questa è viene tradotta in JSON e caricata in una tabella in memoria tramite la funzione OPENJSON. Grazie a questa nuova traduzione, il codice SQL rimane sempre lo stesso a prescindere dagli id usati e così ottimizza le performance deldatabase.
Questo script mostra il codice SQL generato per Sql Server. Tuttavia, questa modifica è stata fatta prima a livello core di EF, e poi a livello di provider per SQL. Questo significa che chi crea i provider per altri database, può sfruttare le modifiche al core per generare un SQL ottimizzato per lo specifico database.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Sviluppare un'interfaccia utente in React con Tailwind CSS e Preline UI
Gestione dei nomi con le regole @layer in CSS
Utilizzare il metodo CountBy di LINQ per semplificare raggruppamenti e i conteggi
Utilizzare Model as a Service su Microsoft Azure
Supporto ai tipi DateOnly e TimeOnly in Entity Framework Core
Sostituire la GitHub Action di login su private registry
Eseguire una query su SQL Azure tramite un workflow di GitHub
Ordine e importanza per @layer in CSS
Esportare ed analizzare le issue di GitHub con la CLI e GraphQL
Potenziare Azure AI Search con la ricerca vettoriale
Cambiare la chiave di partizionamento di Azure Cosmos DB
Supportare lo HierarchyID di Sql Server in Entity Framework 8