在此示例中,如何仅获取具有任何活动Bar的Foos并仅返回集合中的活动Bars?
一种可能的解决方案是这样的,但它需要重新创建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; }
}
修改1
目标是只为这些Foos获得带有任何有效Bar 和的Foos,只有活动的条。
FooA
Bar1 (Active)
Bar2 (Inactive)
FooB
Bar3 (Inactive)
Bar4 (Inactive)
FooC
Bar5 (Active)
Bar6 (Active)
令人失望的结果:
FooA
Bar1 (Active)
FooC
Bar5 (Active)
Bar6 (Active)
正如所提到的许多简单的解决方案,但我想知道Linq是否有任何方法可以在不检索所有Bars的情况下执行此操作,然后在内存中检索所有Bars之后将其置于循环状态。
答案 0 :(得分: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;
答案 1 :(得分: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();
}
答案 2 :(得分:0)
如果您想要从所有Bar
中提取活动Foo
个实例的列表,但不需要知道它们来自哪个Foo
个实例,这应该对您有用:
var activeBars = fooList.SelectMany(f => f.Bars)
.Where(b => b.IsActive)
// .Distinct() /* eliminate duplicates if you want */
.ToList();
SelectMany
运算符将每个Bars
的{{1}}连接成一个序列。 Foo
运算符仅过滤掉活动的运算符。 Where
强制立即填充快照。
这会为您提供ToList()
仅包含List<Bar>
个Bar
个实例。如果两个或多个IsActive == true
可能包含相同的Foo
,并且您希望消除这些重复项,请在Bar
之前添加Distinct()
运算符。
答案 3 :(得分:0)
您可以在select子句中处理Foo对象。 Lambdas不必是简单的表达式,它们可以包含多个语句。
var cleanedList = fooList.Where(f => f.Bars.Any(b => b.IsActive))
.Select(f => {
f.Bars.RemoveAll(b => !b.IsActive);
return f;
}
);