Riutilizzare porzioni di espressioni LINQ

Cristian Civera

di Cristian Civera, in .NET 3.5, venerdì 4 luglio 2008 ore 05.31

Se anche voi usate in alcuni progetti LINQ to SQL come DAL, vi troverete un domain model e le classi create tramite il DBML. Questo perché le prime vengono usate nello strato di presentazione e in quello business, mentre le seconde utilizzate all'interno del DAL realizzato con LINQ to SQL.
Di conseguenza ci ritroviamo a dover mappare le due entità in modi più o meno complessi. Poniamo di avere la classe Customer di LINQ to SQL e quella del domain model (per semplificare con mapping 1:1):

public class CustomerL2S 
{ 
   public int ID { get; set; } 
   public string Description { get; set; } 
} 
public class Customer 
{ 
   public int ID { get; set; } 
   public string Description { get; set; } 
}

In un ipotetico metodo GetSingle che dato l'ID ti dà l'entità, scriviamo qualcosa del genere:

var customer = from c in customers 
            where c.ID == 1 
            select new Customer 
            { 
                ID = c.ID, 
                Description = c.Description 
            };

Poi magari un metodo di List restituisce tutti i Customer, senza filtrarli e purtroppo ci tocca duplicare l'intera query, compreso tutto il mapping, senza la clausola where. Potremmo essere tentati di fare una funzione, così:

var customer = from c in customers 
            where c.ID == 1 
            select GetCustomer(c);

Purtroppo questa tecnica non funziona, perché passiamo una funzione managed al motore di LINQ to SQL che non può passarla a SQL Server. Il problema non sta nella funzione, ma in ciò che essa fa. Infatti la soluzione sta nel lavorare sempre a livello di expression tree. Potremmo infatti creare un extension method (solo per comodità nella chiamata) specifico per il Customer che effettua il mapping che ci permetta di riutilizzarlo più volte:

public static class Extentions 
{ 
   public static IQueryable<Customer> SelectToCustomer(this IQueryable<CustomerL2S> source) 
   { 
       return source.Select(c => new Customer 
       { 
           ID = c.ID, 
           Description = c.Description 
       }); 
   } 
}

Nella funzione accettiamo un IQueryable specifico per l'entità CustomerL2S e sfruttando l'extension method select effettuamo il mapping, ma sempre a livello di espressione, consentendola di portarla su SQL Server. L'utilizzo poi è semplice:

var customer = (from c in customers 
               where c.ID == 1 
               select c).SelectToCustomer();

Il doppio select è d'obbligo per via della query syntax, ma non è un problema poiché la query SQL generata è corretta.

Commenti

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.



Segnala su: Facebook MSDN Social Twitter Segnalo Wikio Diggita Technorati Stumbleupon Google Yahoo FriendFeed Delicious Furl

Nella stessa categoria
I più letti del mese
TagCloud
.NET Framework, .NET Framework 2.0, .NET Framework 3.0, .NET Framework 3.5, .NET Framework 4.0, ADO.NET Entity Framework, AJAX, Architettura, ASP, ASP.NET, ASP.NET 2.0, ASP.NET 2.0 per tutti, ASP.NET 4.0, ASPItalia.com, Custom Control, Databinding, Datagrid, HttpRuntime, IIS, Javascript, LINQ, LINQ to Entities, LINQ to SQL, Media Center, Microsoft Expression, Object Oriented Programming, Off Topic, PDC 2008, Silverlight, Silverlight - animazioni, Silverlight 2.0, Silverlight 3.0, User Control, Visual Studio, Windows 7, Windows CardSpace, Windows Client, Windows Communication Foundation, Windows Live Services, Windows Presentation Foundation, Windows Server, Windows Vista, Windows Workflow Foundation, XAML, XBox 360, XHTML, XML, XPS, XSLT
BLOG INFO
  • 199 post, 86 commenti, 42 trackback
  • Feed blog e contenuti tecnici: RSS
  • Feed blog: RSS Atom
IN EVIDENZA