[英]LINQ Query to Filter Items By Criteria From Multiple Lists
I'm having trouble conceptualizing something that should be fairly simple using LINQ. 我在使用LINQ概念化应该相当简单的东西时遇到了麻烦。 I have a collection that I want to narrow down, or filter, based on the id values of child objects. 我有一个集合,我想根据子对象的id值缩小或过滤。
My primary collection consists of a List of Spots. 我的主要收藏品包括一个斑点列表。 This is what a spot looks like: 这就是现货的样子:
public class Spot
{
public virtual int? ID { get; set; }
public virtual string Name { get; set; }
public virtual string Description { get; set; }
public virtual string TheGood { get; set; }
public virtual string TheBad { get; set; }
public virtual IEnumerable<Season> Seasons { get; set; }
public virtual IEnumerable<PhotographyType> PhotographyTypes { get; set; }
}
I'm trying to filter the list of Spots by PhotographyType and Season. 我正在尝试按照摄影类型和季节过滤斑点列表。 I have a list of ids for PhotographyTypes and Seasons, each in an int[] array. 我有一个关于PhotographyTypes和Seasons的id列表,每个都在int []数组中。 Those lists look like this: 这些列表如下所示:
criteria.PhotographyTypeIds //an int[]
criteria.SeasonIds //an int[]
I want to build a collection that only contains Spots with child objects (ids) matching those in the above lists. 我想构建一个只包含Spots的集合,其子对象(id)与上面列表中的对象相匹配。 The goal of this functionality is filtering a set of photography spots by type and season and only displaying those that match. 此功能的目标是按类型和季节过滤一组摄影点,并仅显示匹配的那些。 Any suggestions would be greatly appreciated. 任何建议将不胜感激。
Thanks everyone for the suggestions. 谢谢大家的建议。 I ended up solving the problem. 我最终解决了这个问题。 It's not the best way I'm sure but it's working now. 这不是我确定的最佳方式,但它现在正在运作。 Because this is a search filter, there are a lot of conditions. 因为这是一个搜索过滤器,所以有很多条件。
private List<Spot> FilterSpots(List<Spot> spots, SearchCriteriaModel criteria)
{
if (criteria.PhotographyTypeIds != null || criteria.SeasonIds != null)
{
List<Spot> filteredSpots = new List<Spot>();
if (criteria.PhotographyTypeIds != null)
{
foreach (int id in criteria.PhotographyTypeIds)
{
var matchingSpots = spots.Where(x => x.PhotographyTypes.Any(p => p.ID == id));
filteredSpots.AddRange(matchingSpots.ToList());
}
}
if (criteria.SeasonIds != null)
{
foreach (int id in criteria.SeasonIds)
{
if (filteredSpots.Count() > 0)
{
filteredSpots = filteredSpots.Where(x => x.Seasons.Any(p => p.ID == id)).ToList();
}
else
{
var matchingSpots = spots.Where(x => x.Seasons.Any(p => p.ID == id));
filteredSpots.AddRange(matchingSpots.ToList());
}
}
}
return filteredSpots;
}
else
{
return spots;
}
}
This may helps you: 这可以帮助您:
List<Spot> spots = new List<Spot>();
Spot s1 = new Spot();
s1.Seasons = new List<Season>()
{ new Season() { ID = 1 },
new Season() { ID = 2 },
new Season() { ID = 3 }
};
s1.PhotographyTypes = new List<PhotographyType>()
{ new PhotographyType() { ID = 1 },
new PhotographyType() { ID = 2 }
};
Spot s2 = new Spot();
s2.Seasons = new List<Season>()
{ new Season() { ID = 3 },
new Season() { ID = 4 },
new Season() { ID = 5 }
};
s2.PhotographyTypes = new List<PhotographyType>()
{ new PhotographyType() { ID = 2 },
new PhotographyType() { ID = 3 }
};
List<int> PhotographyTypeIds = new List<int>() { 1, 2};
List<int> SeasonIds = new List<int>() { 1, 2, 3, 4 };
spots.Add(s1);
spots.Add(s2);
Then: 然后:
var result = spots
.Where(input => input.Seasons.All
(i => SeasonIds.Contains(i.ID))
&& input.PhotographyTypes.All
(j => PhotographyTypeIds.Contains(j.ID))
).ToList();
// it will return 1 value
Assuming: 假设:
public class Season
{
public int ID { get; set; }
//some codes
}
public class PhotographyType
{
public int ID { get; set; }
//some codes
}
You have an array of IDs that has a Contains
extension method that will return true
when the ID is in the list. 您有一个Contains
扩展方法的ID数组,当ID在列表中时,该方法将返回true
。 Combined with LINQ Where
you'll get: 与LINQ结合Where
,你会得到:
List<Spot> spots; // List of spots
int[] seasonIDs; // List of season IDs
var seasonSpots = from s in spots
where s.ID != null
where seasonIDs.Contains((int)s.ID)
select s;
You can then convert the returned IEnumerable<Spot>
into a list if you want: 然后,如果需要,您可以将返回的IEnumerable<Spot>
转换为列表:
var seasonSpotsList = seasonSpots.ToList();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.