2010-08-17 81 views
2

我有以下结构。如何使用LINQ在集合中选择集合?

public class ToolSettings 
{ 
    public string Extension { get; set; } 
    public ObservableCollection<Tool> Tools { get; set; } 
} 

public class Tool 
{ 
    public string Name { get; set; } 
    public string Command { get set; } 
} 

// Within app code 
public ObservableCollection<ToolSettings> settings { get; set; } 

我想抓取扩展等于某个字符串的设置集合中的Tools集合。

下面是我的LINQ代码,但我只知道我的集合中有一个项目,当我知道还有更多。它看起来像它产生一个集合的集合,这就是为什么只有一个项目。

myListBox.ItemsSource = from i in settings 
         where i.Extension == myExtension 
         select i.Tools; 

编辑:

感谢所有的好(快速)的答案。事实证明,我只需要第一个项目,但我知道SelectMany方法将在未来派上用场。所以,感谢所有的领导。这是我使用的完整解决方案。

myListBox.ItemsSource = (from i in settings 
         where i.Extension == myExtension 
         select i.Tools).First(); 

回答

1

这会给你一个IEnumerable<ObservableCollection<Tool>>。它可能只有一个项目,但该项目将是一个ObservableCollection。如果你想要这个集合本身,在最后粘上.First()(或.FirstOrDefault())。

如果i.Extension == myExtension可以在集合中找到几个ToolsSettings(我猜没有),那么你就需要使用.SelectMany()

8
myListBox.ItemsSource = settings.Where(s => s.Extension == myExtension) 
           .SelectMany(s => s.Tools); 

或者,如果你喜欢的查询语法流利的语法:

myListBox.ItemsSource = from s in settings 
         where (s.Extension == myExtension) 
         from t in s.Tools 
         select t; 
+0

你需要翻转方法的顺序调用。 – Shlomo 2010-08-17 14:32:15

+0

SelectMany应该重新命名为更直观的东西,这是很多人难以找到的最有用的linq片段之一,有人问如何做到这一点像一天5次..也许像SelectFlatten或SelectRecursive会让人们更快地将它从intellisense中解脱出来。 – 2010-08-17 14:32:15

0

您可以使用.SelectMany(),但如果你想利用多ToolSettings并选择所有的,这只是真正有用他们的工具作为一个集合。如果Extension是唯一的,则使用.Single()将单个集合的集合减少为单个集合。

0

这个问题有点含糊。你是对的,你正在收集一个集合,因为可能只有一个ToolSettings实例,其中Extension满足您的条件,因此,由于您选择了Tools,因此您将得到一个ObservableCollection<Tool>实例序列。

它听起来像你真的希望得到满足条件的所有Tool实例的顺序。在这种情况下,你要使用的SelectMany extension method on the Enumerable class

myListBox.ItemsSource = settings.Where(i => i.Extension == myExtension). 
    SelectMany(i => i.Tools); 

或者,如果你喜欢的查询语法,你可以做到以下几点:

myListBox.ItemsSource = 
    from i in settings 
    where i.Extension == myExtension 
    from t in i.Tools 
    select t; 

这将转化为对的SelectMany调用编译器时,完成它。

1

试试这个:

myListBox.ItemsSource = (from i in settings 
         where i.Extension == myExtension 
         from t in i.Tools 
         select t);