2011-01-12 12 views
5

Estoy tratando de dividir las consultas de linq a sql para que sean un poco más legibles.Creando fragmentos reutilizables de LINQ to SQL

Digamos que quiero devolver todos los pedidos de productos que en el año anterior tuvieron más de 100 pedidos. Tengo esta consulta:

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; 

Lo que me gustaría ser capaz de hacer es poner la consulta anidada en una función reutilizable:

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

que a su vez me permite cambiar la consulta original a:

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

Esto no funciona sin embargo, con una excepción diciendo que la llamada al método no se puede traducir a SQL cuando se ejecuta la consulta.

¿Algún consejo rápido sobre la forma correcta de lograrlo?

+0

Me lo he estado preguntando pero no he podido preguntar. –

Respuesta

2

¿Qué pasa algo parecido -

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    
);   

?

Sería mejor verificar que el sql producido sea el mismo que el producido por su consulta original.

+0

Eso definitivamente funciona. :) –

0

Acabo de disparar desde la cadera pero ¿ha intentado cambiar el tipo de devolución de LastSeasonOrders a IQueryable<Order>?

+0

El problema es que el proveedor de consultas no puede manejar cualquier llamada de función dentro de la consulta. La función debería haber devuelto 'IQueryable' como dices, pero ese no es realmente el problema aquí. He actualizado la pregunta así que espero que no haya más confusión sobre eso. –