2012-11-20 39 views
1

我試圖重構爲一個查詢這樣的:重構嵌套循環到一個單一的LINQ查詢

while (IsRunning) 
{ 

... 

//specialPoint is a string 
foreach (PointTypeItem pointTypeItem in PointTypeItemCollection) 
    { 
     foreach (PointItem pointItem in pointTypeItem.PointItemCollection) 
     { 
      //Replace the point name with point ID 
      if (specialPoint.Contains(pointItem.PointName)) 
      { 
       replacedCode += s.Replace(specialPoint , pointItem.ID); 
       //I want to go back to the beginning point of while (IsRunning) from here 
       //Simply putting continue; here won't work 
      } 
     } 
    } 
} 

我基本上要變成一個LINQ查詢,但我堅持寫一個。其實,我甚至不確定我是否正在採取這個正確的方向。

var results = from pointTypeItem in ddcItem.PointTypeItemCollection 
       where pointTypeItem.PointItemCollection.Any(pointItem => pointName.Contains(pointItem.PointName)) 
       select //What do I select? 
+0

無論如何,你stil會遍歷每個項目,所以這個重構的目的是什麼? –

+1

什麼是'''什麼是'replacedCode'?你能提供一個簡單的例子和​​期望的結果嗎? –

回答

6
var results = from pointTypeItem in ddcItem.PointTypeItemCollection 
       from pointItem in pointTypeItem.PointItemCollection 
       where specialPoint.Contains(pointItem.PointName) 
       select pointItem.ID; 

得到一個IEnumerable<the type of pointItem.ID>

+0

生病了,我從來不知道你可以在裏面嵌套from子句!謝謝。非常有洞察力 – l46kok

+0

@ l46kok這實際上不是嵌套查詢。它將被轉換爲對「SelectMany」的單個調用,而不是對每個查詢執行查詢。 – Servy

+0

@Richard根據OP中代碼中的註釋,他將在查詢結尾處需要「First」調用。 – Servy

2

你能做到這一點使用的SelectMany()擴展方法:

PointTypeItemCollection.SelectMany(pointCollection => pointCollection.PointItemCollection) 
       .Where(pointItem => pointItem.PointName.Contains(specialPoint)) 
       .Select(pointItem => pointItem.ID); 
0

這是非常難以測試,而無需對這樣的事情的任何值,但什麼?

 replacedCode = string.Concat(
     this.PointTypeItemCollection.SelectMany(i => i.PointItemCollection) 
     .Where(i => specialPoint.Contains(i.PointName)) 
     .Select(i => s.Replace(specialPoint, i.ID)) 
    );