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
Utilizzare Copilot con Azure Cosmos DB
Supportare lo HierarchyID di Sql Server in Entity Framework 8
Bloccare l'esecuzione di un pod in mancanza di un'artifact attestation di GitHub
Cancellare una run di un workflow di GitHub
Applicare un filtro per recuperare alcune issue di GitHub
Effettuare il refresh dei dati di una QuickGrid di Blazor
Eseguire una ricerca avanzata per recuperare le issue di GitHub
Gestione dell'annidamento delle regole dei layer in CSS
Utilizzare il metodo Index di LINQ per scorrere una lista sapendo anche l'indice dell'elemento
Utilizzare il metodo CountBy di LINQ per semplificare raggruppamenti e i conteggi
Creare una libreria CSS universale: Clip-path
Estrarre dati randomici da una lista di oggetti in C#