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)

Altre risorse

Nozioni di base su LINQ in C#

Parole chiave di query (Riferimenti per C#)