我知道已经讨论了很多,但是,作为LINQ的初学者,我没有设法过滤这种情况:
我有一个包含Customers
Projects
列表
要过滤的列表:
List<Customer> Customers {get; set;}
这是客户类:
class Customer
{
public string Name {get; set;}
public List<Project> Projects {get; set;}
}
这是Project class:
class Project
{
public string Name {get; set;}
}
我想要的只是找到所有包含 ONLY 具有特定名称的项目的客户(我的应用将根据项目的名称进行过滤)。
至于现在我有这个:
Customers
.Where(c => c.Projects.Any(p => p.Name.ToLowerInvariant().Contains(lowerCaseFilter)));
但它没有帮助,因为它将返回包含 ALL 项目的所有客户,而不仅仅是我搜索过的项目。
例如,如果我有一个包含15个客户的列表,每个客户的项目数量都是未知数量,我希望只显示那些客户,而仅那些符合搜索条件的客户中的项目术语
我想我在这里错过了一些东西......
答案 0 :(得分:3)
如果要修改列表,则必须重新创建客户和项目:
var searchedCustomers = Customers
.Select(c => new {
Customer = c,
FilteredProjects = c.Projects
.Where(p => string.Equals(p.Name, nameFilter, StringComparison.InvariantCultureIgnoreCase))
.ToList()
})
.Where(x => x.FilteredProjects.Any())
.Select(x => new Customer{
Name = x.Customer.Name,
Projects = x.FilteredProjects
});
我已将String.Equals
与StringComparison.InvariantCultureIgnoreCase
一起使用,以避免创建小写字符串并避免某些本地化问题,例如turkish i problem。因此,您也不需要lowerCaseFilter
这种方法,因此我将其命名为nameFilter
。
答案 1 :(得分:0)
这样的事情:
var customers = Customers
.Select(c => new Customer() { Name = c.Name, Projects = c.Projects == null ? new List<Project>() : c.Projects.Where(p => !string.IsNullOrEmpty(p.Name) && p.Name.ToLower().Contains(lowerCaseFilter)).ToList() })
.Where(c => c.Projects.Any())
.ToList();
您必须创建仅包含所需项目的新Customer对象。
答案 2 :(得分:0)
我不确定你的意思
它不仅会返回包含所有项目的所有客户 我搜索过的那个。
我可以用两种方式解释,请澄清:
(a)的解决方案:
Customers
.Where(c => c.Projects.Any(p => p.Name.ToLowerInvariant().Contains(lowerCaseFilter)))
.Select(c => new Customer
{
// set all other properties
Projects = c.Projects
.Where(p => p.Name.ToLowerInvariant().Contains(lowerCaseFiler))
.ToList()
});
您在此处执行的操作只是按所需值过滤结果的Projects
集合。
(b)的解决方案:
Customers
.Where(c => c.Projects.All(p => p.Name.ToLowerInvariant().Contains(lowerCaseFilter)))
这只是过滤那些仅包含与所需过滤器匹配的项目的项目的客户集合。