Я как-то обычно пишу код чуть проще:
var query = _dbContext.Products.AsQueryable();
if (request.ProductGroups?.Length > 0)
{
query = query.Where(x => request.ProductGroups.Any(y => y == x.ProductGroup));
}
if (request.SupplierIds?.Length > 0)
{
query = query.Where(x => request.SupplierIds.Any(y => y == x.SupplierId));
}
if (request.Categories?.Length > 0)
{
query = query.Where(x => request.Categories.Any( y => y == x.Category));
}
return Task.FromResult(_mapper.ProjectTo<ProductDto>(query));
Общие замечания к коду:
1. Есть ограничения по размеру запроса, если ProductGroups и Categories будут иметь длинные названия, могут быть исключения в рантайме
2. Надо внимательно подумать на счёт ProductGroups и Categories и используемого движка БД — на предмет CaseSensitive и CaseInsensitive сравнений. Могут тоже быть приколы — когда запись из БД вернулась (там CaseInsensitive), а какой-то код на стороне C# не принял эту запись и упал (CaseSensitive).
3. Соответственно, как предложение на подумать — нормализовать ProductGroups и Categories в отдельные таблицы ;)