Quando lavoriamo con un database, una delle operazioni più comuni è il recupero di record che corrispondono a una lista di codici. Spesso questi campi codice non sono la chiave primaria della tabella in quanto si preferisce una chiave surrogata. Supponiamo di avere una tabella Clienti con Id (Identity), Codice e Descrizione e una tabella Ordini con CodiceCliente e DatiOrdine popolata da un sistema esterno. Se volessimo recuperare i clienti relativi agli ordini dovremmo effettuare una join tra le tabelle usando il campo CodiceCliente. Sebbene quest'operazione sia semplice in SQL, con EF Core e LINQ diventa più complessa in quanto dobbiamo eseguire a mano la join. In alternativa, possiamo utilizzare un altro approccio: creiamo una prima query che recupera i codici cliente dalla tabella ordini e successivamente li usa per una IN con la tabella Clienti. Ovviamente il tutto viene fatto con un solo comando SQL, ma creando due query LINQ che si innestano come nell'esempio che segue.
var today = DateTime.Now.Date; IQueryable<string> queryCodiciCliente = Context.Ordini .Where(c => c.DataOrdine == today) .Select(c => c.CodiceCliente) .AsQueryable(); var clienti = Context.Clienti .Where(c => queryCodiciCliente.Contains(c.CodiceCliente)) .ToListAsync();
La prima riga genera una query verso la tabella degli ordini estraendo i codici cliente da recuperare. Poiché non viene eseguita la materializzazione dei dati, EF Core non esegue nessuna query. La seconda riga recupera i clienti per i codici recuperati dalla prima query. Al momento di generare il codice SQL viene generato un solo comando che innesta la prima query nella seconda come evidenziato nel prossimo esempio.
select * from Clienti where CodiceCliente in ( select CodiceCliente from Ordini where DataOrdine = @p0)
L'utilizzo di una join è leggermente più performante dell'approcio qui suggerito. Tuttavia, questo approccio offre la possibilità di spezzettare query complesse in query più semplici e di poterle integrare tra loro semplificando notevolmente il codice LINQ a scapito delle performance. Come sempre la soluzione migliore dipende dal contesto in cui ci si trova.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Creare una libreria CSS universale: Cards
Loggare le query più lente con Entity Framework
Utilizzare il metodo Index di LINQ per scorrere una lista sapendo anche l'indice dell'elemento
Utilizzare Locust con Azure Load Testing
Ottimizzare le performance usando Span<T> e il metodo Split
Creare un webhook in Azure DevOps
Utilizzare il metodo ExceptBy per eseguire operazione di sottrazione tra liste
Persistere la ChatHistory di Semantic Kernel in ASP.NET Core Web API per GPT
Proteggere le risorse Azure con private link e private endpoints
Gestire eccezioni nei plugin di Semantic Kernel in ASP.NET Core Web API
Introduzione ai web component HTML
Utilizzare un numero per gestire la concorrenza ottimistica con SQL Server ed Entity Framework
I più letti di oggi
- a #RealCodeConf4 il 25 maggio a Firenze parleremo di #silverlight4. iscrizioni gratis su http://u.aspitalia.com/g9
- Parallelizzare le chiamate HTTP con async/await e le Promise in JavaScript
- Rendere sicuro l'endpoint di HealthCheck in ASP.NET Core
- #HTML5 schema per avere l'intellisense su #VS2008 (anche express) http://u.aspitalia.com/ed
- Eseguire una chiamata AJAX per inviare dati al server in Angular 2