Operazioni di query LINQ di base (C#)
In questo argomento viene fornita una breve introduzione alle espressioni di query LINQ e ad alcune operazioni comuni eseguite in una query. Informazioni più dettagliate vengono fornite negli argomenti seguenti:
LINQ Query Expressions (C# Programming Guide)
Cenni preliminari sugli operatori di query standard
Nota
Se si ha già dimestichezza con un linguaggio di query, ad esempio SQL o XQuery, è possibile saltare la maggior parte di questo argomento. Per informazioni sull'ordine delle clausole nelle espressioni di query LINQ, consultare la "clausola from" nella sezione successiva.
Come ottenere l'origine dati
In una query LINQ il primo passaggio consiste nello specificare l'origine dati. In C#, come nella maggior parte dei linguaggi di programmazione, per poter utilizzare una variabile è necessario prima dichiararla. In una query LINQ la clausola from deve essere specificata per prima per poter introdurre l'origine dati (customers) e la variabile di intervallo (cust).
//queryAllCustomers is an IEnumerable<Customer>
var queryAllCustomers = from cust in customers
select cust;
La variabile di intervallo è simile alla variabile di iterazione in un ciclo foreach, con la differenza che in un'espressione di query non si verifica un'effettiva iterazione. Quando viene eseguita la query, la variabile di intervallo funge da riferimento per ogni elemento successivo in customers. Poiché il compilatore è in grado di dedurre il tipo di cust, non è necessario specificarlo in modo esplicito. È possibile introdurre ulteriori variabili di intervallo mediante la clausola let. Per ulteriori informazioni, vedere Clausola let (Riferimento C#).
Nota
Per le origini dati non generiche, ad esempio ArrayList, la variabile di intervallo deve essere tipizzata in modo esplicito. Per ulteriori informazioni, vedere Procedura: eseguire una query su un ArrayList con LINQ e Clausola from (Riferimento C#).
Filtraggio
Probabilmente l'operazione di query più comune consiste nell'applicazione di un filtro sotto forma di espressione booleana. Il filtro consente alla query di restituire solo gli elementi per i quali l'espressione sia true. Il risultato viene generato utilizzando la clausola where. Il filtro attivo specifica gli elementi da escludere dalla sequenza di origine. Nell'esempio seguente vengono restituiti solo gli oggetti customers con un indirizzo di Londra.
var queryLondonCustomers = from cust in customers
where cust.City == "London"
select cust;
È possibile utilizzare i comuni operatori logici AND e OR in C# per applicare tutte le espressioni di filtro necessarie nella clausola where. Per restituire, ad esempio, solo i clienti di "Londra" di nome "Davon" mediante l'operatore AND, utilizzare il codice seguente:
where cust.City=="London" && cust.Name == "Devon"
Per restituire i clienti di Londra o Parigi, utilizzare il codice seguente:
where cust.City == "London" || cust.City == "Paris"
Per ulteriori informazioni, vedere Clausola where (Riferimento C#).
Ordinamento
Spesso è utile ordinare i dati restituiti. La clausola orderby consente di ordinare gli elementi presenti nella sequenza restituita in base all'operatore di confronto predefinito per il tipo da ordinare. Ad esempio, la query seguente può essere estesa per ordinare i risultati in base alla proprietà Name. Poiché Name è una stringa, l'operatore di confronto predefinito dispone i risultati in ordine alfabetico dalla A alla Z.
var queryLondonCustomers3 =
from cust in customers
where cust.City == "London"
orderby cust.Name ascending
select cust;
Per disporre i risultati in ordine inverso, ovvero dalla Z alla A, utilizzare la clausola orderby…descending.
Per ulteriori informazioni, vedere Clausola orderby (Riferimento C#).
Raggruppamento
La clausola group consente di raggruppare i risultati in base a una chiave specificata. Ad esempio, è possibile specificare di raggruppare i risultati in base alla chiave City in modo che tutti i clienti di Londra o Parigi vengano suddivisi in singoli gruppi. In tal caso, la chiave è cust.City.
Nota
I tipi sono espliciti negli esempi seguenti in modo da illustrare il concetto. È anche possibile utilizzare la tipizzazione implicita per custQuery, group e customer consentendo al compilatore di determinare il tipo esatto.
// queryCustomersByCity is an IEnumerable<IGrouping<string, Customer>>
var queryCustomersByCity =
from cust in customers
group cust by cust.City;
// customerGroup is an IGrouping<string, Customer>
foreach (var customerGroup in queryCustomersByCity)
{
Console.WriteLine(customerGroup.Key);
foreach (Customer customer in customerGroup)
{
Console.WriteLine(" {0}", customer.Name);
}
}
Quando si termina una query con la clausola group, i risultati vengono visualizzati sotto forma di elenco. Ogni elemento nell'elenco è un oggetto che contiene un membro Key e un elenco di elementi raggruppati sotto quella chiave. Quando si scorre una query che genera una sequenza di gruppi, è necessario utilizzare un ciclo foreach annidato. Il ciclo esterno scorre ogni gruppo e il ciclo interno scorre i membri di ogni gruppo.
Se è necessario fare riferimento ai risultati di un'operazione di gruppo, è possibile utilizzare la parola chiave into per creare un identificatore su cui eseguire un'altra query. Nella query seguente vengono restituiti solo i gruppi che contengono più di due clienti:
// custQuery is an IEnumerable<IGrouping<string, Customer>>
var custQuery =
from cust in customers
group cust by cust.City into custGroup
where custGroup.Count() > 2
orderby custGroup.Key
select custGroup;
Per ulteriori informazioni, vedere Clausola group (Riferimento C#).
Operazioni di join
Le operazioni di join creano associazioni tra sequenze che non vengono create in modo esplicito nelle origini dati. È possibile ad esempio eseguire un join per cercare tutti i clienti e i concessionari che risiedono nella stessa località. In LINQ la clausola join funziona sempre sugli insiemi di oggetti anziché direttamente sulle tabelle di database.
var innerJoinQuery =
from cust in customers
join dist in distributors on cust.City equals dist.City
select new { CustomerName = cust.Name, DistributorName = dist.Name };
In LINQ non è necessario utilizzare join come in SQL poiché le chiavi esterne in LINQ sono rappresentate nel modello a oggetti come proprietà che contengono un insieme di elementi. Ad esempio, un oggetto Customer contiene un insieme di oggetti Order. Invece di eseguire un join, è possibile accedere agli ordini utilizzando la notazione del punto:
from order in Customer.Orders...
Per ulteriori informazioni, vedere Clausola join (Riferimento C#).
Selezione (proiezioni)
La clausola select genera i risultati della query e specifica la "forma" o il tipo di ogni elemento restituito. Ad esempio, è possibile specificare se i risultati devono essere costituiti da oggetti Customer completi, solo da un membro, da un sottoinsieme di membri o da un tipo di risultati completamente diverso basato su un calcolo o sulla creazione di un nuovo oggetto. Quando la clausola select genera un risultato diverso da una copia dell'elemento di origine, l'operazione viene denominata proiezione. L'utilizzo delle proiezioni per la trasformazione dei dati è una funzionalità potente delle espressioni di query LINQ. Per ulteriori informazioni, vedere Trasformazioni dati con LINQ (C#) e Clausola select (Riferimento C#).
Vedere anche
Riferimenti
Tipi anonimi (Guida per programmatori C#)
Concetti
LINQ Query Expressions (C# Programming Guide)
Operazioni di query di base (Visual Basic)