Alessandro Del Sole's Blog

{ A programming space about Microsoft® .NET® }
posts - 1909, comments - 2047, trackbacks - 352

My Links

News

Your host

This is me! Questo spazio è dedicato a Microsoft® .NET®, di cui sono molto appassionato :-)

Cookie e Privacy

Microsoft MVP

My MVP Profile

Microsoft Certified Professional

Microsoft Specialist

Xamarin Certified Mobile Developer

Il mio libro su VB 2015!

Pre-ordina il mio libro su VB 2015 Pre-ordina il mio libro "Visual Basic 2015 Unleashed". Clicca sulla copertina per informazioni!

Il mio libro su WPF 4.5.1!

Clicca sulla copertina per informazioni! E' uscito il mio libro "Programmare con WPF 4.5.1". Clicca sulla copertina per informazioni!

These postings are provided 'AS IS' for entertainment purposes only with absolutely no warranty expressed or implied and confer no rights.
If you're not an Italian user, please visit my English blog

Le vostre visite

I'm a VB!

Guarda la mia intervista a Seattle

Follow me on Twitter!

Altri spazi

GitHub
I miei progetti open-source su GitHub

Article Categories

Archives

Post Categories

Image Galleries

Privacy Policy

Eager loading fortemente tipizzato in ADO.NET Entity Framework e Visual Basic 2008

In un post di qualche giorno fa abbiamo visto come realizzare un form per la rappresentazione master-details con Visual Basic 2008 e ADO.NET Entity Framework e abbiamo detto che, utilizzando la modalità proposta, perdiamo parte dell’essenza di LINQ andando ad eseguire l’eager loading dei “many” relazionati alla parte “one” della relazione utilizzando una stringa piuttosto che una rappresentazione fortemente tipizzata, tipica, invece, di LINQ stesso.

 

Nel post si fa cenno al blog di Matthieu Mezil (Microsoft Visual C# MVP), il quale ha risolto il problema implementando un metodo che estende l’Include e che consente di utilizzare un’espressione Lambda al posto della stringa. Il codice proposto da Matthieu è in Visual C# ma, tramite l’aiuto dello stesso, lo abbiamo convertito in Visual Basic 2008.

 

Nonostante la sua brevità, si tratta di codice che richiede una certa conoscenza di LINQ, pertanto ho inserito appositi link sugli oggetti discussi.

 

Riprendiamo la stessa piccola demo proposta nel precedente post, disponibile in area download di VB T&T, ed aggiungiamo un nuovo modulo all’interno del quale spicca, in primo luogo, la seguenti direttive Imports:

 

Imports System.Runtime.CompilerServices

Imports System.Data.Objects

Imports System.Linq.Expressions

Imports System.Reflection

 

Fatto questo, scriviamo il seguente codice che implementa il metodo extension in questione. I metodi extension sono una speciale caratteristica di .NET Framework 3.5 e, se avete letto il mio libro su LINQ in VB 2008, ne avete avuto un’ampia descrizione. Ecco il modulo, che commenteremo di seguito:

 

<Extension()> Module ObjectQueryExtension

 

    <Extension()> _

    Function Include(Of T)(ByVal MainQuery As ObjectQuery(Of T), _

                           ByVal SubSelector As Expression(Of Func(Of T, Object))) _

                           As ObjectQuery(Of T)

 

        Return MainQuery.Include(CType(CType(CType(SubSelector.Body,  _

                                 UnaryExpression).Operand,  _

                                 MemberExpression).Member,  _

                                 PropertyInfo).Name)

    End Function

End Module

 

I metodi extension debbono essere decorati con l’attributo Extension e sono contenuti in moduli decorati con il medesimo attributo. Il metodo Include è di tipo generico Of T. Il primo argomento che il metodo stesso riceve è di tipo ObjectQuery(Of T), che rappresenta, in forma fortemente tipizzata, una query eseguita nei confronti dell’Entity Data Model. Nel nostro caso, l’ObjectQuery è costituito dall’oggetto NorthwindContext.Categories. Il secondo argomento, di tipo Expression (Of TDelegate), costituisce una rappresentazione strongly typed di un’espressione lambda che assume la forma strutturale di un expression tree.

Nel corpo del metodo si richiama il metodo Include sull’istanza dell’ObjectQuery ricevuta (quindi sempre NorthwindContext.Categories nel nostro esempio). Il corpo dell’espressione lambda viene convertito in una UnaryExpression. L’operatore di questa espressione ottenuto (Operand) viene convertito in una MemberExpression, ossia l’infrastruttura per l’accesso a un campo o una proprietà, a cui si accede per il tramite della reflection.

 

L’utilizzo di questo extension method è molto semplice. Se riprendiamo il codice illustrato la scorsa volta, sostituiremo la riga di codice inerente l’eager loading in questo modo:

 

        'Dim dataSource = NorthwindContext.Categories.Include("Products")

 

        Dim dataSource = NorthwindContext.Categories.Include(Function(c) c.Products)

 

La differenza è abbastanza evidente. Non stiamo più specificando i dati da recuperare attraverso una stringa, bensì attraverso un’espressione lambda che ci permette di eseguire l’operazione in forma strongly typed, con tutti i vantaggi che ne derivano. L’inferenza del tipo determina correttamente c come di tipo Categories e dataSource come di tipo ObjectQuery(Of Categories).

 

Se provate ad avviare l’applicazione, noterete che il risultato sarà il medesimo della scorsa volta, ma noi abbiamo ragionato e operato in modo decisamente migliore.

 

Alessandro

Print | posted on mercoledì 19 novembre 2008 17:42 | Filed Under [ .NET Framework Visual Basic Visual Studio 2008 LINQ ]

Powered by:
Powered By Subtext Powered By ASP.NET