#107 - Passare un Expression di Entity Framework attraverso un servizio WCF
di Cristian Civera, in Entity Framework, Windows Communication Foundation, 13 marzo 2009
ADO.NET Entity Framework è un ORM targato Microsoft che tra le principali caratteristiche ha il grande punto di forza di poter essere utilizzato con LINQ to Entities per facilitare l'interrogazione e la manipolazione dei dati. Questo è possibile grazie a LINQ e in particolare all'interfaccia IQueryable che permette di creare un grafo di oggetti di tipo Expression che sono in grado di rappresentare un espressione al fine di consentire a motori, come LINQ to SQL o LINQ to Entities, di trasformarlo in una query ANSI SQL.
Il difetto di questo approccio è che tale espressione, e in generale LINQ, sono legati alla tecnologia .NET e non possono essere trasportati al di fuori di questo mondo. Per esempio, se si sviluppa un servizio WCF che permette l'interrogazione dei prodotti, è necessario che si definisca un'operazione per ottenere una lista ed eventualmente fornire come parametro una struttura che permetta di filtrare per uno o più campi, di ordinare o di paginare. Qualunque scelta si faccia, è molto probabile che la struttura definita sia comunque limitata e non adatta a coprire tutte le esigenze che i potenziali consumer del servizio possano aver bisogno.
Sul sito di MSDN è a disposizione all'indirizzo http://code.msdn.microsoft.com/exprserialization del codice di esempio che mostra come serializzare e deserializzare in XML un Expression, perciò l'idea di questo script è di proporre di usare tale codice per creare un servizio che riceva l'espressione della query da creare e la esegua con LINQ to Entities (nell'esempio MSDN viene usato LINQ to Sql).
Si prenda in esame questo codice che effettua una normale query:
NorthwindEntities ne = new NorthwindEntities(); // Preparazione della query da effettuare string s = "Italy"; IQueryable query = ne.ProductSet.Where(p => p.UnitPrice > 0 && p.Suppliers.Country == s);
La proprietà query.Expression rappresenta il grafo di oggetti dell'espressione che non è ancora stata eseguita. Il ToString restituisce il seguente simil codice C#:
value(System.Data.Objects.ObjectQuery`1[EFWebApplication.Product]).Where(p => ((p.UnitPrice > Convert(0)) && (p.Suppliers.Country = value(EFWebApplication._Default+<>c__DisplayClass0).s)))
La parola value sta ad indicare una costante che in questo caso è ObjectQuery
Ecco quindi come risulta facile, con le classi incluse nello script, serializzare una query:
// Creazione serializzatore delle espressioni ExpressionSerializer serializer = new ExpressionSerializer(); // Convertitore speciale apposito per Entity Framework serializer.Converters.Add(new EFCustomExpressionXmlConverter(ne, serializer)); // Serializzo l'expression in xml xmlExpression = serializer.Serialize(query.Expression);
Di seguito invece come deserializzare l'espressione e creare una query per l'entità Product:
// Deserializzo l'expression dall'xml Expression ex = serializer.Deserialize(xmlExpression); // Creo la query sulla base dell'expression deserializzata IQueryable<Product> r = ((IQueryable)ne.CreateQuery<Product>("*")).Provider.CreateQuery<Product>(ex);
Il limite principale di questa tecnica risiede che non si possono effettuare query complesse laddove vengono valutate classi presenti sul consumer. Queste infatti non possono essere serializzate e si può fare solo riferimento a variabili calcolate prima della preparazione dell'expression. Non è possibile inoltre usare delegate ad eccezione delle lampda e non è possibile fare query miste con LINQ to *.
Con questa tecnica un servizio può ricevere come parametro l'XML dell'espressione oppure, per automatizzare il tutto, si può valutare l'uso di un DataContractSerializerOperationBehavior per specificare il surrogate per la serializzazione tramite DataContractSerializer dell'Expression o lavorare direttamente con un IClientMessageInspector/IDispatchMessageInspector per intervenire sull'XML SOAP.
Nota: Questo script contiene un allegato.
Approfondimenti
-
#160 - Forzare il caricamento dei metadati con Entity Framework
-
Scopri i nostri nuovi libri su ASP.NET 4.0, C# 4 e Visual Basic 2010: in offerta lancio al 20% di sconto!
-
Entity Framework ed NHibernate a confronto
-
Documentazione MSDN e versioni del .NET Framework
-
Real Code Day 4.0: costruire applicazioni reali - Firenze
-
Template per generare classi POCO con Entity Framework 4.0
-
WPF e Siverlight: Dispatcher e finestre modali
-
RT @brada Windows API Code Pack for #netfx http://u.aspitalia.com/d
-
Real Code Day 4: Accesso ai dati con Entity Framework
-
#169 - Sfruttare msbuild per differenziare il config
-
.NET Framework 4.0 beta 1: ASP.NET MVC
-
#111 - Personalizzare la serializzazione delle entità di ADO.NET Data Services

















Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.