2011-01-12 162 views
5

我想分解LINQ到SQL查詢,使它們更具可讀性。創建LINQ to SQL的可重用塊

假設我想返回上一年有超過100個訂單的產品的所有訂單。我有這個疑問:

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; 

我想什麼能夠做的就是把嵌套查詢的可重複使用的功能:

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

,然後讓我改變原來的查詢:

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

但是,如果運行查詢時無法將方法調用轉換爲SQL,則此方法無效。

有關正確實現此目的的任何快速提示?

+0

我一直在想這個,但不能自問。 – 2011-01-12 04:19:55

回答

2

什麼樣的東西 -

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

這將是最好的驗證,生產的SQL是由您的原始查詢產生的相同。

+0

這絕對有效。 :) – 2011-01-12 21:47:50

0

我只是從臀部拍攝,但你有沒有試過改變返回類型LastSeasonOrdersIQueryable<Order>

+0

問題是查詢提供者不能處理查詢中的任何函數調用。如你所說,該函數應該返回`IQueryable`,但這不是真正的問題。我已經更新了這個問題,所以希望沒有更多的困惑。 – 2011-01-12 10:38:21