Freeteo


Pensieri e C#dice di Matteo Raumer

Generare lambda expression a runtime può tornare utile

In un recente progetto mi è capitato di dover generare un filtro per una query Linq dinamicamente da codice, in particolare, avevo a disposizione un metodo che accettava come parametro una Expression ma la classe T era di tipo "Entity" e non un'implementazione del "MioOggettoBase", quindi non aveva nel modello la proprietà che intendevo usare nell'expression.

Nel dettaglio: l'applicazione era in Silverlight ed avevo un ViewModelBase dove T : Entity, quindi il relativo DataContext si aspettava una query su T, il che tutto funziona se siamo all'implementazione reale dove specifico il tipo di T, ad esempio "Cliente, Pratica etc..." ossia classi del mio modello...in poche parole: 
dovevo generare una lambda del tipo: (x => x.ID == 1234) senza avere dall'intellisense quella proprietà "Id".

Se non ricordo male, con le ultime versioni di Silverlight e RiaServices è possibile specificare una classe base custom e probabilmente non avrei avuto questi problemi, ma al tempo non potevo farlo, quindi mi sono scritto un piccolo metodo che mi genera proprio quella Lambda da codice, ovvero l'ExpressionTree equivalente, ricevendo l'Id numerico come parametro :

private Expression<Funcbool>> GetIDExpression(int id)
{
   //--- genero dinamicamente il filtro "(x=> x.ID == id)"

   ParameterExpression x = Expression.Parameter(typeof(T), "x");
   Expression prop = Expression.PropertyOrField(x, "ID");
   ConstantExpression val = Expression.Constant(id, typeof(int));
   BinaryExpression uguale = Expression.Equal(prop, val);

   Expression<Funcbool>> filtro = Expression.Lambda<Funcbool>>(uguale, new ParameterExpression[] { x });
   return filtro;
}
 

Questo è un esempio banale, all'aumentare della complessita dell'ExpressionTree da generare le righe di codice aumentano parecchio, e soprattutto non è così intuitivo avere sott'occhio tutto questa pappardella di oggetti, legati tramite l'operatore etc.
Sicuramente è sempre utile sapere che è possibile farlo, soprattutto quando avete già in piedi una bella architettura e non volete toccarla per queste piccole eccezioni.

Lascio qui qualche link per approfondire l'argomento:
http://msdn.microsoft.com/en-us/library/bb397951.aspx
http://www.albahari.com/nutshell/predicatebuilder.aspx
http://channel9.msdn.com/Events/DevDays/DevDays-2011-Netherlands/Devdays097
http://blogs.msdn.com/b/csharpfaq/archive/tags/expression+trees/default.aspx
http://marlongrech.wordpress.com/2008/01/08/working-with-expression-trees-part-1/

 

Categoria: Tips
sabato, 21 mag 2011 Ore. 16.41

Messaggi collegati






  • Views Home Page: 187.743
  • Views Posts: 333.429
  • Views Gallerie: 340.795
  • n° Posts: 163
  • n° Commenti: 148
Anno 2014

Anno 2013

Anno 2012

Anno 2011

Anno 2010

Anno 2009

Anno 2008

Anno 2007

Anno 2006

Anno 2005
Copyright © 2002-2007 - Blogs 2.0
dotNetHell.it | Home Page Blogs
ASP.NET 2.0 Windows 2003