2012-11-20 41 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)) 
    );