2010-08-17 4 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 из коллекции настроек, где Extension равно определенной строке.

Ниже мой код LINQ, но я получаю только один элемент в своей коллекции, когда знаю, что есть больше. Похоже, что он создает коллекцию коллекции, поэтому есть только один элемент.

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

EDIT:

Спасибо за все хорошие (и быстрые) ответы. Оказывается, мне нужен только первый элемент, но я знаю, что метод 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

+0

SelectMany следует переименовать в нечто более интуитивно понятное, это один из самых полезных элементов linq, с которым так много людей сталкиваются с трудностями при поиске, есть кто-то, спрашивающий, как это сделать, как 5 раз в день.Возможно, например, SelectFlatten или SelectRecursive заставят людей быстрее вытащить его из intellisense для этой цели. –

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); 
Смежные вопросы