主列表根据匹配值从其他列表中过滤

时间:2016-04-12 14:42:37

标签: c# linq

想象一下:

您有一个可以分配到一个或多个国家/地区的人员。 可以将同一个人分配到一个或多个站点 可以将同一个人分配到一个或多个地区

用户可以选择要过滤的国家/地区,网站和区域,并且只应显示符合该条件的用户。

我正在使用来自我拥有的数据源的内存集合,并且想要找出能够过滤满足所有标准的人(人)的最佳方式,即:

用户可以选择网站,地区和国家,并且对于所有这些组合,我想带回符合此标准的人员列表。

任何想法如何?

Person对象的结构如下:

ID
Name
Countries (List)
Regions (List)
Sites (List)

我似乎无法找出正确的LINQ语法来过滤主列表,以便让我只满足那些符合所选条件的人。

任何指导都表示赞赏。

3 个答案:

答案 0 :(得分:1)

如果保存用户选择,请说:

var chosenCountries = new List<Country>();
var chosenRegions  = new List<Region>();
var chosenSite = new List<Site>();

然后它只是过滤那些

var result = persons;
if(chosenCountries.Any())
{
result = result.Where(p=>p.Countries.Any(c=>chosenCountries.Any(cc=>cc.Id == c.Id));
}
if(chosenRegions.Any())
{
result = result.Where(p=>p.Regions.Any(r=>chosenRegions.Any(cr=>cr.Id == r.Id));
}
return result.Distinct().ToList();

答案 1 :(得分:1)

var countryIdsToCheck = new List<int> { 1,3,5 };
var regionIdsToCheck = new List<int> { 6,8 };
var siteIdsToCheck= new List<int> { 35 };

var result = yourDbContext.Persons;
if(countryIdsToCheck.Any())
{
  result= result.Where(s=>s.Countries.Any(x=>countryIdsToCheck.Contains(x.Id));
}
if(regionIdsToCheck.Any())
{
  result= result.Where(s=>s.Regions.Any(y=>regionIdsToCheck .Contains(y.Id));
}
if(siteIdsToCheck.Any())
{
  result= result.Where(s=>s.Sites.Any(z=>siteIdsToCheck.Contains(z.Id));
}
var finalResult=result.ToList();

或单线

var result = yourDbContext.Persons
              .Where(s=>s.Countries.Any(x=>countryIdsToCheck.Contains(x.Id))
                  || s.Regions.Any(y=>regionIdsToCheck.Contains(y.Id))
                  || s.Sites.Any(z=>siteIdsToCheck.Contains(z.Id))).ToList();

ToList()无需致电。我添加了它,以便它可以帮助您使用快速监视和断点进行调试(ToList()执行表达式并将结果复制一个新列表(急切加载))

答案 2 :(得分:0)

如果过滤器对象如下所示,我将展示其他替代方案:

public class Filter
{
    public int CountryID;
    public int RegionID;
    public int SiteID;
}

var filter = new List<Filter>();

var result = persons.Where(p => 
       filter.Any(f => p.Countries.Any(c => c.ID == f.CountryID) &&
                  f => p.Regions.Any(r => r.ID == f.RegionID) &&
                  f => p.Sites.Any(s => s.ID == f.SiteID)));