如何使用LINQ选择集合中的子集合?

4
我有以下结构。
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; }

我想从设置集合中获取工具集合,其中扩展等于某个字符串。
以下是我的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();
5个回答

13
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;

你需要颠倒方法调用的顺序。 - Shlomo
SelectMany 应该被重命名为更直观的名称,它是 Linq 中最有用的部分之一,但很多人都难以找到它。每天都有人问如何做这个操作。也许像 SelectFlatten 或 SelectRecursive 这样的名称可以让人们更快地从智能感知中找到它。 - Jimmy Hoffa

3

这将为您提供一个 IEnumerable<ObservableCollection<Tool>>。它可能只有一个项目,但该项目将是一个 ObservableCollection。如果您想要该集合本身,请在末尾添加 .First()(或 .FirstOrDefault())。

如果 i.Extension == myExtension 在集合中找到多个 ToolsSettings(我猜不会),那么您需要使用 .SelectMany()


1

试试这个:

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

0
问题有点模糊。你是对的,你得到了一个集合的集合,因为可能只有一个ToolSettings实例满足你的条件,所以由于你选择了Tools,你得到了一系列ObservableCollection<Tool>实例。
听起来你真正想要的是获取所有符合条件的Tool实例的序列。在这种情况下,你需要使用Enumerable类上的SelectMany扩展方法
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的调用。


0
你可以使用`.SelectMany()`,但只有在你想把多个ToolSettings并且选择它们所有的Tools作为一个单独的集合时,才真正有用。如果Extension是唯一的,可以使用`.Single()`来将一个单个集合的集合缩减为仅包含单个集合。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接