Introduzione a LINQ

LINQ è l’acronimo di Language INtegrated Query, ed è una delle novità del .NET Framework 3.5. Rappresenta il primo framework Microsoft per l’accesso ai dati, indipendente dall’architettura e dalle strutture cui si tenta di accedere e totalmente integrato all’interno dei linguaggi .NET di alto livello.

Con LINQ possiamo eseguire query e manipolare dati sfruttando un modello indipendente dalle varie tipologie di fonti; possiamo infatti accedere a database, file di testo, file XML, array, file Excel, file di configurazione, informazioni su assembly, chiavi di registro e qualsiasi altro oggetto riconducibile ad una collezione di oggetti enumerabile; il tutto utilizzando un unico modello di programmazione che riunisce molteplici tecniche differenti di accesso ai dati.

Per il corretto funzionamento di questo nuovo linguaggio, sono state aggiunte nuove funzionalità ai linguaggi del .NET Framework 3.5, in grado di supportare l’esecuzione delle query.

Sia per C# che per VB.NET abbiamo a disposizione nuove keyword, il meccanismo delle variabili locali implicite e dei tipi anonimi, gli inizializzatori di oggetti e collezioni, gli extension methods e le lambda expression.

LINQ porta con sé una serie di nuovi tool e funzionalità per migliorare la produttività. Il framework a supporto dell’accesso ai dati permette il mapping degli oggetti di SQL Server (Tabelle, viste, stored, etc.) su classi .NET (un vero e proprio ORM) ed è stata creata una sintassi particolare per accedere tramite LINQ a informazioni in formato XML e a strutture come DataSet e DataTable.

Le funzionalità appena descritte sono state fatte confluire in queste quattro implementazioni di LINQ:

  • LINQ to Objects – permette di eseguire delle query su collezioni di oggetti in memoria
  • LINQ to XML – permette di eseguire delle operazioni su informazioni in formato XML
  • LINQ to DataSet – permette di eseguire delle query su DataSet tipizzati
  • LINQ to SQL – permette di rappresentare un grafo di oggetti in memoria che rappresentano gli oggetti presenti in un database SQL Server, su cui poi eseguire delle query

L’insieme di queste implementazioni fornisce un potente strumento per la gestione dei dati in memoria, derivati da varie fonti diverse fra loro.

Vediamo un esempio in cui vogliamo recuperare tutti i numeri pari da un array di interi. La query è molto semplice, ma permette perfettamente di vedere la nuova sintassi LINQ e una piccola parte delle nuove keyword disponibili.

Query per i numeri pari (C#)

int[] numeri = { 1, 2, 3, 4, 5 };

var numeriPari = from n in numeri where (n%2 == 0) select n;

foreach (var item in numeriPari)
Console.WriteLine(“{0}”, item);

Query per i numeri pari (VB.NET)

Dim numeri As Integer() = New Integer() {1, 2, 3, 4, 5}

Dim numeriPari = From n In numeri Where (n Mod 2 = 0) Select n

For Each item In numeriPari
Console.WriteLine(“{0}”, item)
Next

La sintassi LINQ è molto simile a quella utilizzata per accedere ad una qualsiasi base di dati, ma è molto importante chiarire un concetto: LINQ non è solo un tool per utilizzare SQL.

Nell’esempio proposto abbiamo una fonte di dati rappresentata da un array di interi predefinito, una variabile implicita che rappresenta il risultato della nostra query di selezione (la variabile numeriPari) e la query vera e propria che seleziona i numeri pari (utilizzando la variabile n come valore generico della collezione di oggetti su cui effettuare il controllo tramite la clausola where).

Proprio per permettere la scrittura di query LINQ sono state introdotte in entrambi i linguaggi queste nuove keyword:

  • from – è la keyword di inizio di ogni query LINQ e specifica la fonte di dati nella quale dovrà essere eseguita la query.
  • where – è la clausola che specifica quali elementi saranno ritornati dalla query; applica una sorta di filtro di selezione.
  • select – è la clausola che definisce i tipi di valori che saranno prodotti dalla query.
  • group ( Group By in VB.NET) – è la clausola che raggruppa i risultati secondo una certa chiave.
  • orderby (Order By in VB.NET) – effettua l’ordinamento (ascendente o discendente).
  • join – permette di effettuare prodotti cartesiani tra più fonti di dati, come in SQL. Anche qui possiamo definire inner join o outer join.
  • into (valida solo per C#) – è la keyword contestuale che indica in quale variabile temporanea vengono salvati i risultati di una select, di un group o di un join.
  • let – è la keyword che permette di salvare temporaneamente il risultato di una subquery per poi utilizzarlo all’interno della query principale.
  • Take (valida solo per VB.NET) – clausola che ritorna il numero specifico dei numeri contigui dall’inizio di una collezione.
  • Distinct – clausola che restringe il numero dei valori ritornati da una query eliminando i duplicati (valida solo per VB.NET ma in C# si può usare il metodo Distinct()).

Grazie alle modifiche sui linguaggi del .NET Framework e alle aggiunte funzionali come le variabili implicite (nel nostro esempio “numeriPari” risulta una variabile che implicitamente viene dichiarata di tipo IEnumerable), possiamo utilizzare LINQ per effettuare rapidamente operazioni, su collezioni di oggetti, che prima avrebbero richiesto molte righe di codice, cicli e condizioni di controllo.

Nell’esempio appena visto, abbiamo effettuato una selezione su una collezione di oggetti in memoria; questa funzionalità fa parte dell’implementazione “LINQ to Objects” che ci permette di eseguire specifiche operazioni sulle collezioni di oggetti. Questa implementazione è la base di tutte le query LINQ e viene abilitata non appena viene inserito il namespace System.Linq nelle direttive using (o Imports per VB.NET).


LINQ to SQL

LINQ to SQL risulta sicuramente l’implementazione più importante di LINQ. Ci permette di scrivere query di selezione, inserimento, modifica o cancellazione su dati prelevati da un database SQL Server, integrate direttamente nel codice C# o VB.NET. Tutto questo basandosi su un modello ad oggetti che rispecchia perfettamente (con una forma di mappatura uno a uno) le strutture presenti all’interno della base di dati.

Per essere ancora più chiari LINQ to SQL è un ORM (Object Relational Mapping) che permette di modellare la struttura del proprio database relazione attraverso classi .NET; tale ORM può essere poi interrogato attraverso la sintassi LINQ per permettere all’utente di eseguire query “CRUD” sulle informazioni presenti all’interno del database. Ad oggi, sono però solamente supportati database SQL Server.

Il lavoro che fa praticamente questo ORM è quello di tradurre le query integrate al linguaggio scelto (quindi query LINQ) in query SQL per l’esecuzione sulla base di dati e, in seguito, di tradurre il risultato della query in strutture dati tabulari costituenti delle istanze di oggetti vere e proprie. Una query LINQ di questo tipo quindi:

(C#)

ORMDataContext context = new ORMDataContext();

var customers = from c in context.Customers
                where c.City == "London"
                orderby c.ContactName
                select c;

(VB.NET)

Dim context As New ORMDataContext()

Dim result = From c In context.Customers _
             Where c.City = "London" _
             Select c

verrà poi eseguita all’interno del database secondo questa sintassi SQL:

SELECT [CustomerID],[CompanyName],[ContactName],[ContactTitle],[Address],
       [City],[Region],[PostalCode],[Country],[Phone],[Fax]
FROM [Northwind].[dbo].[Customers]
WHERE [City] = 'London'

aumentando notevolmente la facilità di scrittura del codice per l’accesso ai dati relazionali all’interno delle proprie applicazioni (considerando che non ci si deve più preoccupare di creare una connessione al database, lanciare un comando, etc.).

Se invece, vogliamo inserire un nuovo record all’interno del database, non dobbiamo fare altro che creare l’informazione da inserire utilizzando le strutture definite dal mapping LINQ to SQL e sottomettere il nuovo dato all’oggetto che si occupa di gestire le comunicazioni tra l’applicazione e il database.

(C#)

ORMDataContext context = new ORMDataContext();

Customer c = new Customer();
c.CustomerID = "FACEITWEB";
c.City = "Salerno";
c.ContactName = "Pippo Pluto";
c.Address = "Via del Mare";
c.CompanyName = "faceitweb.com";

context.Customers.InsertOnSubmit(c);
context.SubmitChanges();

(VB.NET)

Dim context As New ORMDataContext()

Dim c As New Customer
c.CustomerID = "FACEITWEB"
c.City = "Salerno"
c.ContactName = "Pippo Pluto"
c.Address = "Via del Mare"
c.CompanyName = "faceitweb.com"

context.Customers.InsertOnSubmit(c)
context.SubmitChanges()

Gli esempi di aggiornamento del database e di cancellazione di record sono stati omessi, ma comunque presenti all’interno del codice da scaricare; sicuramente non vi risulterà difficile immaginare che anche in questi ultimi due casi, il modo in cui vengono effettuate operazioni sulla base di dati tramite LINQ to SQL sarà sempre di una semplicità disarmante.

Le potenzialità di LINQ to SQL risultano essere veramente tante e soprattutto, ormai, risulta la scelta ottimale basarsi su di un ORM per gestire l’accesso ai dati e la loro persistenza, all’interno delle proprie applicazioni.

The LINQ Project
HTML.it: Introduzione a LINQ

You can leave a response, or trackback from your own site.

4 Responses to “Introduzione a LINQ”

  1. upnews.it scrive:

    Introduzione a LINQ | FaceitWeb.com…

    LINQ è l’acronimo di Language INtegrated Query, ed è una delle novità del .NET Framework 3.5. Rappresenta il primo framework Microsoft per l’accesso ai dati, indipendente dall’architettura e dalle strutture cui si tenta di accedere e totalment…

  2. diggita.it scrive:

    Introduzione a LINQ | FaceitWeb.com…

    LINQ è l’acronimo di Language INtegrated Query, ed è una delle novità del .NET Framework 3.5. Rappresenta il primo framework Microsoft per l’accesso ai dati, indipendente dall’architettura e dalle strutture cui si tenta di accedere e totalment…

  3. Fix scrive:

    La keyword “Let” è presente anche nel linguaggio Vb.Net

  4. admin scrive:

    Hai ragione Fix. Grazie

Leave a Reply

Subscribe to RSS Feed Follow me on Twitter!