2013-06-05 103 views
2

我有一個複雜的查詢,我在代碼中使用了好幾次。我用它來獲得所有項目或只是一個項目:可擴展的Linq查詢

from item in _db.Tests ... select getItem(item) 
from item in _db.Tests ... where item.Id == id select getItem(item) 

我想不重複的公共部分,只叫「的getItem」我是否會使用它。

我試圖創建一個這樣的功能:

from item in _db.Tests ... 

但是編譯器會抱怨,因爲我確實不是一個選擇。

我還可以創建一個:

private IQueryable<Test> getTests() 
{ 
    return from item in _db.Tests ... select item; 
} 

,然後調用它像這樣:

from t in getTests() select getItem(t) 

但是,這可能不會利用優化LINQ是能夠的,對吧?

你能幫我嗎?

編輯

我意識到我的問題是比較複雜的:點(...)實際上是連接和爲getItem功能使用信息,從連接和做一些計算。我想有一個函數來獲取所有的項目和一個不同的項目來獲得一個特定的項目(我想從程序的其餘部分隱藏查詢邏輯)。

我想這樣做的:

private IQueryable<Tuple<Table1, Table2, Table3, Table4>> queryItems() 
{ 
    return from t1 in _db.Table1s 
      join t2 in _db.Table2s on t1.T2ID equals t2.ID into outerT2 from t2 in outerT2.DefaultIfEmpty() 
      join t3 in _db.Table3s on t1.T3ID equals t3.ID into outerT3 from t3 in outerT3.DefaultIfEmpty() 
      join t4 in _db.Table4s on t1.T4ID equals t4.ID into outerT4 from t4 in outerT4.DefaultIfEmpty() 
      select new Tuple<Table1, Table2, Table3, Table4>(t1, t2, t3, t4); 
} 

public IEnumerable<Item> GetItems() 
{ 
    return from i in queryItems() 
      select getItem(i.Item1, i.Item2, i.Item3, i.Item4); 
} 

public Item GetItem(int id) 
{ 
    return from i in queryItems() 
      where i.Item1.ID equals id 
      select getItem(i.Item1, i.Item2, i.Item3, i.Item4); 
} 

我不希望把中的getItem因爲queryItems它做一些計算,並在的GetItem(INT ID)的情況下,將運行它每個元素(對吧?)。

這是做這份工作的好方法嗎?有更漂亮的方法嗎?更有效的方法?

+0

流利的語法?試試看。 –

+0

@newStackExchangeInstance如果使用方法或查詢語法,則無關緊要。兩人都有能力做他想做的事。 – Servy

+0

@Servy它會更容易。 –

回答

6

您可以使用相同的查詢,並只需添加一個條件,如果需要:

var items = from item in _db.Tests ... select getItem(item); 

// Restrict as necessary 
if (fetchSingle) 
    items = items.Where(item => item.Id == id); 

拆分過濾網(Where)到一個單獨的通話將沒有缺點,因爲它會發送相同的查詢由於LINQ的延期執行,實際使用結果爲IQueryable<T>的服務器。

+0

請注意,如果他的投影不投射「Id」,他可能無法在調用'GetItem'後應用該位置。 – Servy

+0

@Servy True - 之後可能需要這樣做。 –

3

但是,這可能不會使用優化LINQ是能夠......對嗎?

錯誤。直到您實際嘗試迭代查詢時,查詢提供程序試圖將IQueryable轉換爲實際的數據庫查詢並執行它。當你有這樣的東西:

var query = db.SomeTable; 

你還沒有提取整個表;你已經取得什麼也沒有。如果你有:

var query2 = query.Where(item => item.SomeProperty == "someValue"); 

然後查詢提供程序將應用該過濾器到它發送到數據庫的查詢。

要理解發生的事情,最簡單/最好的方法是查看數據庫上下文的Log值。它會在您執行查詢時確切指示,以及查詢是什麼。然後你可以確定你正在執行的是你應該在什麼時候的查詢。