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
Sopprimere gli errori di concorrenza quando si elimina una entity con Entity Framework 7
Applicare il versioning ai nostri endpoint ASP.NET Core Minimal API
Definire lo stile CSS in base alle dimensioni del container
Le novità di .NET 7 e C# 11
Sfruttare l'output cache di ASP.NET Core 7 con i controller
YARP: un reverse proxy in ASP.NET Core
Effettuare il deploy di immagini solo da container registry approvati in Kubernetes
Usare gateway dedicati con Azure Cosmos DB per migliorare le prestazioni
Abilitare HTTP/3 in ASP.NET Core 7.0
Leggere i dati di configurazione di ASP.NET Core da Azure Key Vault
Caricare un asset come parte di una release con un workflow di GitHub
Sfruttare la local cache del browser tramite gli ETag in ASP.NET Core
I più letti di oggi
- devConf 2022 - Online
- .NET Conference Italia 2022 - Milano e Online
- Blazor Conference 2021 - Online
- Visual Studio 2019 Live - Milano
- .NET Conference Italia 2021 - Online
- Novità di ASP.NET Core 1.1
- L'object model di Microsoft SharePoint - Seconda parte
- Visual Studio 2010 per l'architetto
- Visual Studio 2017 e il supporto a Docker per ASP.NET Core
- Anteprima di ASP.NET Core 3