2014-08-25 3 views
1

В этом примере, как получить только Foos, которые имеют активную панель и возвращать только активные бары в коллекции?Выбор подмножества коллекции с Linq

Одним из возможных решений является чем-то вроде этого, но это требует воссоздания Foo элементы:

fooList 
    .Where(f => f.Bars.Any(b => b.IsActive)) 
    .Select(f => new Foo() 
    { 
     Name = f.Name, 
     Bars = f.Bars.Where(b => b.IsActive).ToList() 
    }); 
public class Foo 
{ 
    public string Name { get; set; } 

    public ICollection<Bar> Bars { get; set; } 
} 

public class Bar 
{ 
    public string Name { get; set; } 

    public bool IsActive { get; set; } 
} 

Edit 1

Цель состоит в том, чтобы получить только FOOS с любым активным баром и для этих Foos, только активные бары.

FooA 
    Bar1 (Active) 
    Bar2 (Inactive) 
FooB 
    Bar3 (Inactive) 
    Bar4 (Inactive) 
FooC 
    Bar5 (Active) 
    Bar6 (Active) 

Disired результат:

FooA 
    Bar1 (Active) 
FooC 
    Bar5 (Active) 
    Bar6 (Active) 

Как заостренный Theres много простых решений, но мне интересно, если Linq имеет какой-либо способ сделать это без извлекать все бары, а затем падение неактивного в цикле как после того, как все Бары были извлечены в память.

+5

Ну да, вы должны создать новые объекты 'Foo' - потому что существующие объекты 'Foo' могут иметь неактивные ссылки« Bar ». Что бы вы хотели, чтобы решение действительно возвращало, если не новые объекты? Вы действительно заботитесь только о объектах «Бар»? (Если это так, это легко.) Если бы вы могли описать «форму» нужного результата, реализация должна быть простой. –

+0

Просто интересно, есть ли какое-то конкретное решение для такого рода проблемы (всегда пытаюсь узнать что-то новое) :) –

+3

Ну, без особого контекста, мы действительно не знаем, что вы подразумеваете под «такой проблемой». LINQ не позволяет одному объекту одновременно не иметь активных объектов «Бар» и сохраняет свою предыдущую информацию, если это то, о чем вы думали ... –

ответ

1

Вы должны использовать

Добавление данных в список

List<Foo> employees = new List<Foo>(); 
Foo employee = new Foo(); 
employee.Name = "Emp1"; 
employee.Bars = new List<Bar>(); 
employee.Bars.Add(new Bar { Name = "Alpesh", IsActive = true }); 
employee.Bars.Add(new Bar { Name = "Krunal", IsActive = true }); 
employee.Bars.Add(new Bar { Name = "Karthik", IsActive = false }); 
employee.Bars.Add(new Bar { Name = "Rakesh", IsActive = true }); 
employees.Add(employee); 

Получение активного данных Только

List<Foo> newList = employees.Select(m => new Foo 
     { 
      Name = m.Name, 
      Bars = m.Bars.Where(u => u.IsActive == true).ToList() 
     }).ToList(); 
return newList; 
+0

вы можете использовать это как: var ty = employees.Select (m => new Foo {Name = m.Name, Bars = m.Bars.Where (u => u.IsActive == true) .ToList()}) .К списку(); также – cracker

0

Если вы не хотите, чтобы заново создать Foo's затем использовать цикл

foreach(var foo in fooList.Where(f => f.Bars.Any(b => b.IsActive))) 
{ 
    foo.Bars = foo.Bars.Where(b => b.IsActive).ToList(); 
} 
0

Если вы хотите получить список активных Bar экземпляров тянули из всех Foo, но не нужно знать, какие Foo случаи они пришли, это должно работать для вас:

var activeBars = fooList.SelectMany(f => f.Bars) 
         .Where(b => b.IsActive) 
        // .Distinct() /* eliminate duplicates if you want */ 
         .ToList(); 

оператор SelectMany конкатенации в Bars от каждого Foo в петь le последовательности. Оператор Where отфильтровывает только активные. ToList() заставляет мгновенный снимок.

Это дает вам List<Bar>, содержащий только Bar экземпляры, где IsActive == true. Если два или более Foo могут содержать то же самое Bar, и вы хотите устранить эти дубликаты, то добавьте оператор Distinct() до ToList().

0

Вы можете обрабатывать объекты Foo в предложении select. Lambdas не должны быть простыми выражениями, они могут содержать несколько операторов.

var cleanedList = fooList.Where(f => f.Bars.Any(b => b.IsActive)) 
         .Select(f => { 
              f.Bars.RemoveAll(b => !b.IsActive); 
              return f; 
             } 
           ); 
Смежные вопросы