LINQ
1️⃣ Che cos'è LINQ?
LINQ (Language-Integrated Query) è una funzionalità di C# che permette di eseguire query su collezioni di dati utilizzando una sintassi simile al linguaggio SQL. È stato introdotto per facilitare la manipolazione dei dati, migliorando la leggibilità e la manutenibilità del codice. LINQ può essere utilizzato con diversi tipi di collezioni, come:
- Collezioni in memoria (liste, array, dizionari)
- Database (utilizzando LINQ to SQL o Entity Framework)
- Documenti XML (LINQ to XML)
- File di testo o fonti di dati esterne
2️⃣ Come funziona LINQ?
LINQ offre due modalità di scrittura delle query:
- Sintassi delle query (simile a SQL)
- Sintassi dei metodi (utilizza i metodi delle collezioni)
Entrambe le sintassi producono lo stesso risultato, ma la scelta tra le due dipende dal contesto e dalle preferenze di leggibilità.
3️⃣ Sintassi delle Query di LINQ
Esempio di Query LINQ di base
Immaginiamo di avere una lista di numeri e di voler selezionare solo quelli pari:
List<int> numeri = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// Sintassi delle query LINQ
var numeriPari = from numero in numeri
where numero % 2 == 0
select numero;
foreach (var numero in numeriPari)
{
Console.WriteLine(numero); // Output: 2, 4, 6, 8, 10
}
- from – Specifica la fonte dei dati (in questo caso,
numeri
).
- where – Filtra i dati in base a una condizione.
- select – Specifica i dati da includere nel risultato.
4️⃣ Sintassi dei Metodi LINQ
LINQ supporta anche una sintassi alternativa basata sui metodi, utilizzando i metodi disponibili su IEnumerable
e IQueryable
. La sintassi dei metodi è più compatta e si adatta meglio a query complesse.
// Sintassi dei metodi LINQ
var numeriPariMetodi = numeri.Where(numero => numero % 2 == 0);
foreach (var numero in numeriPariMetodi)
{
Console.WriteLine(numero); // Output: 2, 4, 6, 8, 10
}
In questo caso, Where
è il metodo che filtra la collezione in base alla condizione specificata.
5️⃣ Operazioni Comuni in LINQ
LINQ supporta numerose operazioni comuni che rendono il lavoro con i dati molto più semplice e intuitivo. Vediamo alcuni metodi utili.
1. Where
– Filtro
var numeriGrandi = numeri.Where(numero => numero > 5);
2. Select
– Proiezione
Select
è usato per trasformare ogni elemento della collezione.
var numeriDoppi = numeri.Select(numero => numero * 2);
3. OrderBy
e OrderByDescending
– Ordinamento
var numeriOrdinati = numeri.OrderBy(numero => numero);
var numeriOrdinatiDecrescente = numeri.OrderByDescending(numero => numero);
4. First
e FirstOrDefault
– Primo elemento
First
restituisce il primo elemento che soddisfa una condizione o genera un'eccezione se non lo trova. FirstOrDefault
restituisce null
o il valore di default del tipo.
var primoPari = numeri.First(numero => numero % 2 == 0); // 2
var primoPariODefault = numeri.FirstOrDefault(numero => numero % 2 == 0); // 2 o default se non trovato
5. Count
– Conta gli elementi
var conteggioPari = numeri.Count(numero => numero % 2 == 0); // 5
6. Any
– Verifica se esistono elementi
Any
restituisce true
se almeno un elemento soddisfa la condizione specificata.
bool esistonoPari = numeri.Any(numero => numero % 2 == 0); // true
6️⃣ Query complesse con LINQ
Ecco un esempio più complesso che combina diverse operazioni.
Immaginiamo di avere una lista di oggetti Studente
, ciascuno con nome, età e voto.
public class Studente
{
public string Nome { get; set; }
public int Età { get; set; }
public double Voto { get; set; }
}
List<Studente> studenti = new List<Studente>
{
new Studente { Nome = "Anna", Età = 20, Voto = 28.5 },
new Studente { Nome = "Marco", Età = 22, Voto = 24.0 },
new Studente { Nome = "Luca", Età = 19, Voto = 30.0 },
new Studente { Nome = "Sara", Età = 21, Voto = 27.5 }
};
// Query per trovare tutti gli studenti maggiorenni con voto maggiore di 25, ordinati per voto
var studentiFiltrati = studenti
.Where(s => s.Età >= 18 && s.Voto > 25)
.OrderByDescending(s => s.Voto)
.Select(s => s.Nome);
foreach (var nome in studentiFiltrati)
{
Console.WriteLine(nome); // Output: Luca, Anna, Sara
}
7️⃣ Esempio completo: Gruppo e Aggregazione
Possiamo utilizzare LINQ per creare gruppi e aggregare dati. In questo esempio raggrupperemo gli studenti per età e calcoleremo il voto medio per ogni gruppo di età.
var gruppoPerEtà = studenti
.GroupBy(s => s.Età)
.Select(g => new
{
Età = g.Key,
MediaVoto = g.Average(s => s.Voto)
});
foreach (var gruppo in gruppoPerEtà)
{
Console.WriteLine($"Età: {gruppo.Età}, Media Voto: {gruppo.MediaVoto}");
}
8️⃣ Sintesi dei Vantaggi di LINQ
- Leggibilità: La sintassi di LINQ rende le query sui dati più leggibili e simili a SQL.
- Manutenibilità: I metodi LINQ riducono la complessità e migliorano la manutenibilità del codice.
- Efficienza: LINQ è ottimizzato per gestire dati con operazioni più rapide e sicure.
📑 Esercizi
Alcuni esercizi:
- Filtro e selezione: Data una lista di numeri interi, trova tutti i numeri dispari e moltiplicali per 3.
- Ordinamento e proiezione: Data una lista di stringhe rappresentanti nomi di città, ordinale in ordine alfabetico e convertili tutte in maiuscolo.
- Aggregazione: Data una lista di oggetti
Studente
, calcola il voto medio, il voto minimo e il voto massimo.