2012-07-11 53 views
3

我是linq中的新成員。所以有時候只是不明白linq是如何工作的。所以在VS2010 IDE中有任何工具或內建機制來詳細調試linq執行。假設我有這個linq查詢如何調試LINQ結果

var to_search = new[] { "Geo", "JCB" }; 

var result = from sr in list 
      let w = to_search.FirstOrDefault(ts => sr.Title.ToLower().Contains(ts.ToLower())) 
      where w != null 
      let a = new {sr=sr, word=w.ToLower()} 
      group a by a.word into g 
      orderby g.Count() descending 
      let sorted = g.OrderByDescending(a=> a.sr.Title.Select((c, i) => a.sr.Title.Substring(i)).Count(sub => sub.ToLower().StartsWith(a.word))) 
      from a in sorted 
      select a.sr; 

var completeList = result.Concat(list.Except(result)); 

如何詳細調試上面的linq查詢。請指導我。謝謝。

+0

爲什麼不把它分解成小塊,並寫每個單元的單元測試?然後寫一個整體的單元測試? – 2012-07-11 20:31:56

+0

請看這篇文章 http://stackoverflow.com/questions/118341/how-to-debug-a-linq-statement – james31rock 2012-07-11 20:33:18

+0

調試LINQ結果的一部分困難是它將默認爲IEnumerable 並被評估懶惰,所以傳統的VS IDE調試工具只會幫助你。我推薦LINQPad,如果你想在LINQ中塗鴉和玩結果。 – 2012-07-11 20:37:32

回答

5

很多都可以寫回應這個看似簡單的問題!事實上,我已經在Simple-Talk.com上的文章LINQ Secrets Revealed: Chaining and Debugging中詳細寫過。下面是它的要點總結:

  • 您可以進入與調試一些LINQ查詢,但在查詢依賴於表達式和語句的組成(因爲你只能跨上聲明) 。
  • LINQ方法鏈由於基本規則而起作用:每個非終端方法以IEnumerable<T>作爲輸入並返回IEnumerable<T>作爲輸出。
  • 如果您願意,只要符合該基本規則,您可以注入一個「禁止使用」聲明來給您一個「墊腳石」。也就是說,意識到你總是可以將.Select(z => z)放在方法鏈中,而不會產生任何後果,請使用其中的變體:z => { return z; }
  • 您可以類似地注入一種診斷方法來提供輸出,而不僅僅提供一個潛在的斷點。 LINQPad,不僅僅是LINQ,而是一般的C#的優秀暫存器,它以其強大的Dump()方法的幌子提供了這一點。轉儲是一種對象可視化工具,可提供令人驚歎的複雜數據結構可視化。
  • 根據Bart De Smet在其內容豐富的文章LINQ to Objects – Debugging中的工作,您可以將Dump的簡化版帶回到Visual Studio中 - 我提供的代碼附在頂部提到的文章中。
  • 感謝Robert Ivanc在LINQPad Visualizer上的工作,您甚至可以將LINQPad可視化工具帶入Visual Studio(儘管您需要手動爲單個表達式啓動它;您無法將其掛接到Dump()方法)。

作爲一個簡單的例子,考慮這個簡單的方法鏈:

string[] Words = new string[] 
{" KOOKABURRA", "Frogmouth", "kingfisher ", "loon", "merganser"}; 

Words 
     .Select(word => word.Trim()) 
     .Select(word => word.ToLower()) 
     .Where(word => word.StartsWith("k")) 
     .OrderBy(word => word); 

一旦你包括轉儲擴展方法在Visual Studio項目,您可以微創儀器像這樣...

Words 
    .Select(word => word.Trim()) 
    .Dump() 
    .Select(word => word.ToLower()) 
    .Dump() 
    .Where(word => word.StartsWith("k")) 
    .Dump() 
    .OrderBy(word => word) 
    .Dump(); 

...或更多精心這樣的...

Words 
    .Dump(w => "ORIGINAL: " + w, ConsoleColor.Yellow) 
    .Select(word => word.Trim()) 
    .Dump(w => "TRIMMED: " + w, ConsoleColor.Yellow) 
    .Select(word => word.ToLower()) 
    .Dump(w => "LOWERCASE: " + w, ConsoleColor.Green) 
    .Where(word => word.StartsWith("k")) 
    .Dump(w => "FILTERED to 'K': " + w, ConsoleColor.Red) 
    .OrderBy(word => word) 
    .Dump(w => "SORTED: " + w, ConsoleColor.Blue); 

...得到的輸出呈現爲無論是左側或圖的右側,分別爲: Diagnostic output from Dump method in Visual Studio

作爲一個傳情,我會說雖然這確實很有用,但您確實必須看到LINQPad可以使用相同的輸出(here再次爲您提供方便)所做的增強可視化。

0

我相信你應該可以像往常一樣在任何其他代碼中放置中斷點。我不是100%確定的,因爲我經常將LINQ語法寫成匹配的擴展方法。

但是,這是另一種選擇,您可以使用擴展方法重寫查詢,並在每個方法上添加斷點。

如果有疑問,不過,用F11 :)

此外,LINQPad應該能夠幫助一個好一點這裏。

+0

LINQPad如何幫助我調試結果。如何在linqpad中設置斷點。你能幫我指導嗎?我可以下載免費版本的linqpad。請在這裏發佈圖像,這可以幫助我可視化調試linq查詢在所有步驟中的詳細信息。假設例如什麼被存儲在讓a或讓w。什麼是獲得通過作爲一個值爲c amd我a.sr.Title.Select((c,我)。如何調試這種方式。尋求幫助。謝謝 – Thomas 2012-07-12 07:04:38