2011-01-12 12 views
5

Sto cercando di suddividere le query da linq a sql per renderli un po 'più leggibili.Creazione di blocchi riutilizzabili da LINQ a SQL

Dire che voglio restituire tutti gli ordini per prodotto che nell'anno precedente aveva più di 100 ordini. Ho questa domanda:

from o in _context.Orders 
where (from o1 in _context.Orders 
     where o1.Year == o.Year - 1 && o1.Product == o.Product 
     select o1).Count() > 100 
select o; 

Quello che mi piacerebbe essere in grado di fare è mettere la query nidificate in una funzione riutilizzabile:

private IQueryable<Order> LastSeasonOrders(Order order) 
{ 
    return (from o in _context.Orders 
      where o.Year == order.Year - 1 && o.Product == order.Product 
      select o); 
} 

che poi mi fa cambiare la query originale a:

from o in _context.Orders 
where LastSeasonOrders(o).Count() > 100 
select o; 

Questo non funziona però con un'eccezione dicendo che la chiamata al metodo non può essere tradotto a SQL durante l'esecuzione della query.

Eventuali suggerimenti rapidi sul modo corretto per raggiungere questo obiettivo?

+0

Mi stavo chiedendo da solo ma non riuscivo a chiedermelo. –

risposta

2

Che dire qualcosa di simile -

void Main() 
{ 
    TypedDataContext _context = ... 

    var query = 
     (
      from o in _context.Orders 
      where LastSeasonOrders(_context , o).Count() > 100 
      select o  
     ); 
    ... 
}  


public static Func<TypedDataContext, Order, IQueryable<Order>> 
    LastSeasonOrders = CompiledQuery.Compile 
    ((TypedDataContext _context, Order order) => 

     from o in _context.Orders 
     where o.Year == order.Year - 1 && o.Product == order.Product 
     select o    
);   

?

Sarebbe meglio verificare che lo sql prodotto sia lo stesso di quello prodotto dalla query originale.

+0

Che funziona sicuramente. :) –

0

Sto sparando dal fianco ma hai provato a cambiare il tipo di ritorno da LastSeasonOrders a IQueryable<Order>?

+0

Il problema è che il provider di query non può gestire solo una chiamata di funzione all'interno della query. La funzione avrebbe dovuto restituire "IQueryable" come dici tu, ma qui non è proprio questo il problema. Ho aggiornato la domanda quindi spero che non ci sia più confusione su questo. –