score:1

Accepted answer

One (brutal) way to do it:

public ActionResult Filter(IList<SelectedFilter> selectedFilters) {
       var model = new List<Shirt>();
       IEnumerable<Shirt> ListOfShirts = db.GetAllShirts();

        IEnumerable<Shirt> filteredListOfShirts = ListOfShirts
           .Where(shirt => {
               return (
                    (selectedFilters.Any(filter => filter.Name == "Color" && !string.IsNullOrWhiteSpace(filter.Value)) ? // is Color filter set?
                        selectedFilters.Any(filter =>
                        {
                            return (filter.Name == "Color" && shirt.Color == filter.Value);
                            }) : true)
                    &&
                    (selectedFilters.Any(filter => filter.Name == "Size" && !string.IsNullOrWhiteSpace(filter.Value)) ? // is Size filter set?
                        selectedFilters.Any(filter =>
                       {
                           return (filter.Name == "Size" && shirt.Size == filter.Value);
                       }) : true)
                    &&
                    (selectedFilters.Any(filter => filter.Name == "Type" && !string.IsNullOrWhiteSpace(filter.Value)) ? // is Type filter set?
                        selectedFilters.Any(filter =>
                        {
                            return (filter.Name == "Type" && shirt.Type == filter.Value);
                        }) : true)
                    );
               });

        model = filteredListOfShirts.ToList();

   }

That should also work if you have multiple filter values with same name

{Name="Color",Value="Red"},{Name="Color",Value="Blue"}

score:1

You could write a method which checks to see if a given Shirt is in a filter, then use All to check for each one.

public static void Filter(IList<SelectedFilter> selectedFilters)
{
    var filters = selectedFilters
        .GroupBy(i => i.Name);

    var filteredShirts = db
        .GetAllShirts()
        .Where(shirt => filters.All(filter => ShirtInFilter(filter, shirt)));
}

public static bool ShirtInFilter(
    IGrouping<string, SelectedFilter> filter,
    Shirt shirt)
{
    var values = filter.Select(i => i.Value);

    switch (filter.Key)
    {
        case "Color":
            return values.Contains(shirt.Color);
        case "Size":
            return values.Contains(shirt.Size);
        case "Type":
            return values.Contains(shirt.Type);
        default:
            return false;
    }
}

The switch could be eliminated if you want to access properties using reflection, but that seems like overkill for your use case.


Related Query

More Query from same tag