LINQ To SQL - Parte II

LINQ rappresenta una delle novità più importanti per lo sviluppo nella prossima release di Visual Studio.

LINQ è una serie di estensioni al linguaggio, sia per C# che VB.NET, che ci permettono di utilizzare degli operatori "alla SQL" per lavorare su diverse sorgenti dati.

Questa è la quarta parte di una serie di post. Negli altri post ho affrontato i segueti argomenti:

In questo post continuo l'esplorazione di Linq to SQL. Spero che le altre puntate siano state utili :-). Grazie delle mail :-)

Nel post precedente trovate tutti i riferimenti passo-passo su come partire a realizzare la prima applicazione con Linq to SQL in una console application. Ho cominciato a mostrare come utilizzare il designer di VS 2008 per effettuare il mappaggio tra le tabelle di un databbase SQL server con le classi della nostra applicazione, quelle che costituiranno l' Obect Model dell'applicazione stessa. Sempre nella prima parte ho mostrato come effettuare operazioni di query usando la sintassi offerta da LINQ.

Ma se voglio aggiungere un nuovo record nel mio database o modificarne uno esistente come faccio?

Update

Se voglio modificare un oggetto e poi fare in modo che questo venga persistito nel database l'operazione è molto semplice: faccio tutte le modifiche del caso e quando voglio persitere lo stato del mio oggetto sul database invoco il metodo SubmitChanges() .

C#

clip_image002

VB.NET

clip_image004

In figura vedete la query generata per l'esecuzione del codice in C#. Nel precedente post ho raccontato come abilitare il trace degli statements SQL generati da LINQ.

clip_image006

Notate che è stata generata una sola query per la selezione del prodotto: SELECT TOP 1 ... questo grazie al Deferred Execution Model con cui LINQ lavora: ho espresso infatti la query LINQ con due blocchi di codice distinti, il primo per selezionare tutti i prodotti di una certa categoria, il secondo per ottenere il primo prodotto in base all'operatore .First() .

La seconda query è quella che forza l'Update del nostro prodotto selezionato e che viene generata da LINQ perchè abbiamo effettuato la chiamata a SubmitChanges(). Guardate come la clausola di update va a selezionare il prodotto che andrà ad oggiornare: LINQ si accorge se ci sono state modifiche fatte da altri prima di lanciare la query. LINQ gestisce quella che viene definata come Optimistic Concurrency: in sostanza l'aggiornamento del nostro prodotto, va a buon fine solo se non sono state apportate modifiche al prodotto stesso da quando lo abbiamo precedentemente letto.

Insert/Delete

L'inserimento di un nuovo prodotto segue linee simili.

clip_image008

Ho creato una nuova istanza dell' oggetto Product, che rappresenta il prodotto da aggiungere al database. Ho stampato nella console  l'ID del prodotto prima e dopo l'aggiornamento. Se eseguite il codice noterete che dopo la SubmitChanges(), tale valore è cambiato è rappresenta correttamente la chiave che la corrispondente riga ha nella tabella del database.

Se voglio cancellare un prodotto, in VB.NET posso scrivere:

clip_image010

In questo caso ho usato la Remove alla quale dovevo passare un prodotto, quello da cancellare appunto, così dopo aver fatto una query che mi poteva ritornare anche più prodotti ho usato il metodo First per selezionare il primo.

Con una Lamba Expression ...

Avrei potuto scrivere la stessa cosa usando una sintassi equivalente:

clip_image012

Nel codice precedente vedete che ho indicato l'intenzione di selezionare  un solo prodotto invocando il metodo Single su Products, il codice che ho utilizzato nelle parentesi mi ha permesso di fare la selezione opportuna). L'espressione usata in figura è una lamba Expression, una delle novità di C# 3.0.

Si può pensare ad una Lamba Expression come ad una modalità offerta dal linguaggio per scrivere del codice in-line. Avrei infatti potuto esprimere lo stesso codice in C# 2.0 in modo più verboso usando un metodo anonimo.

Ok probabilmente ci sarebbe da fare qualche esempio in più ... in questo articolo trovate meglio descritte le Espressioni Lambda in VB.NET.

Anche in VB.NET è possibile utilizzare una Lambda Expression, ecco come:

clip_image014

Aggiungere un prodotto alla Categoria "Beverages"

Negli esempi visti in precedenza ho semplicemente aggiunto un prodotto nel nostro database inizializzando alcune proprietà come ad esempio il nome del prodotto stesso. Ok, ma abbiamo visto che un prodotto è in relazione molti-a-1 con la tabella categoria, il prodotto ha infatti un campo CategoryID, che è un intero, e che permette di navigare nel database e trovare la corrispondente riga nella tabella categoria e quindi sapere qual è il nome della categoria stessa ....

Come faccio quindi ad aggiungere un prodotto in una specifica categoria, di cui conosciamo il nome, come ad esempio "Beverages" ? Linq To SQL ci permette di navigare in modo molto semplice tra gli oggetti della nostra applicazione e quindi selezionata una specifica categoria possiamo facilmente aggiungere un nuovo prodotto .

Ok troppe parole, ecco il codice:-)))

clip_image016

Quello che succede sul database, lo vediamo andando a "spulciare" la query generata :

clip_image018

La query mostra la INSERT del nuovo prodotto in cui viene impostato il nome "Nuova Bevanda 2", come volevamo; notiamo , però, che viene anche impostata la categoria, tramite l 'ID della stessa, che nel nostro esempio è 1. La cosa interessante è che nel codice che abbiamo scritto con LINQ non abbiamo impostato l'ID della categoria, ma ne abbiamo usato il nome e così abbiamo aggiunto un nuovo prodotto tra quelli della categoria "Beverages", molto più semplice vero?

Conclusione

In questo post abbiamo visto come tramite LINQ to SQL siamo in grado di gestire anche le operazioni di Insert/Update e Delete dei nostri oggetti, a cui LINQ fa corrispondere una query sul database. LINQ non solo ci permette questo, ma per di più semplifica l'interazione con il database semplificandone la navigazione: abbiamo aggiunto un prodotto alla categoria "beverages" senza preoccuparci della relazione tra prodotto e categoria.

Insieme al post precedente spero di essere riuscito a mostrarvi come sia semplice scrivere uno strato di accesso ai dati usando LINQ to SQL. Il tutto semplificato dall'aiuto offerto dall designer di Visual Studio 2008,  dall' Intellisense e dal fatto che le interrogazioni che facciamo con LINQ sono strong-typed.

Ma c'è molto altro ... stay tuned!

In questo articolo LINQ to SQL viene presentato in modo chiaro e completo.

LINQ to SQL: .NET Language-Integrated Query for Relational Data (articolo MSDN in inglese)

Espressioni Lambda in VB.NET.

Percorso:

Per chi non ha seguito passo-passo consiglio il seguente percorso con laboratori:

  1. Scaricare la beta 2 di Visual Studio 2008
  2. Laboratori di Linq in C#
  3. Laboratori di Linq in VB.NET

Ciao e alla prossima.

-Pietro