LINQ to SQL: Chiamare extension method non implementati

di Cristian Civera, in .NET 3.5,

Credo che qualcuno si sia già imbatutto in un problema dovuto ad una query LINQ to SQL simile a questa:

bool MiaFunzione(Customer c)
{
    return true;
}

var customer = from c in dc.Customers
               where MiaFunzione(c)
               select c;

Se lo eseguiamo otterremo un exception perché MiaFunzione è un metodo managed e non può essere valutato tramite una query SQL. L'esempio può sembrare palese, ma in realtà questo problema c'è anche con extesion method come Contains o tutti quelli che accettano un IEqualityComparer, non portabile sul SQL Server.

Poiché quando chiamiamo un extension method il compilatore individua il metodo che come argomento vuole il tipo più vicino alla variabile, quando interroghiamo dc.Customers, la cui proprietà è di tipo Table<T> che a sua volta implementa IQueryable<T>, andiamo a chiamare i metodi contenuti nella classe System.Linq.Queryable i quali lavorano sull'espressione, per poi essere valuta, trasformata in query SQL ed eseguita, all'effettivo consumo dell'enumeratore.
Se però il tipo è IEnumerable<T> andiamo a chiamare i metodi della classe System.Linq.Enumerable, non lavorando più sull'espressione, ma aggiungendo nuovi iteratori che valuteranno T ad ogni ciclo.

Di conseguenza, per risolvere i problema basta effettuare un downcast su IEnumerable<T> o meglio ancora l'extesion method AsEnumerable.

var customer = from c in dc.Customers.AsEnumerable()
               where MiaFunzione(c)
               select c;

Attenzione però, così facendo l'extension method Where consuma l'intero dc.Customers ottenuto da SQL Server, di conseguenza viene scaricata l'intera tabella dal DB per poi essere filtrata con LINQ to Object. Il alcuni casi potrebbe andare bene, in altri no; basta saperlo.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

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

Nella stessa categoria
I più letti del mese