Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ Query to Filter Items By Criteria From Multiple Lists

Tags:

c#

.net

search

linq

I'm having trouble conceptualizing something that should be fairly simple using LINQ. I have a collection that I want to narrow down, or filter, based on the id values of child objects.

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. 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. 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.

like image 354
Don Fitz Avatar asked Jan 17 '26 21:01

Don Fitz


1 Answers

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;
        }
    }
like image 73
Don Fitz Avatar answered Jan 20 '26 11:01

Don Fitz