Я написал код, позволяющий фильтровать продукты на нашем сайте, и у меня довольно неприятный запах кода.Пользователь может выбрать 1- * из этих фильтров, что означает, что мне нужно быть конкретным с предложением WHERE
.
Я думаю, что я ищу способ построения лямбда-выражения, поэтому для каждого фильтра яможет «изменить» мое предложение WHERE
- но я не уверен, как это сделать в .NET, и должен быть способ.
Код в его текущем состоянии (эффективно закодированный, а не динамический, будетболь, чтобы добавить больше параметров фильтра).
public static class AgeGroups
{
public static Dictionary<string, int> Items = new Dictionary<string, int>(){
{ "Modern (Less than 10 years old)", 1 },
{ "Retro (10 - 20 years old)", 2 },
{ "Vintage(20 - 70 years old)", 3 },
{ "Antique(70+ years old)", 4 }
};
public static IQueryable<ProductDTO> FilterAgeByGroup(IQueryable<ProductDTO> query, List<string> filters)
{
var values = new List<int>();
var currentYear = DateTime.UtcNow.Year;
foreach (var key in filters)
{
var matchingValue = Items.TryGetValue(key, out int value);
if (matchingValue)
{
values.Add(value);
}
}
if (Utility.EqualsIgnoringOrder(values, new List<int> { 1 }))
{
query = query.Where(x => x.YearManufactured >= currentYear - 10);
}
else if (Utility.EqualsIgnoringOrder(values, new List<int> { 2 }))
{
query = query.Where(x => x.YearManufactured <= currentYear - 10 && x.YearManufactured >= currentYear - 20);
}
else if (Utility.EqualsIgnoringOrder(values, new List<int> { 3 }))
{
query = query.Where(x => x.YearManufactured <= currentYear - 20 && x.YearManufactured >= currentYear - 70);
}
else if (Utility.EqualsIgnoringOrder(values, new List<int> { 4 }))
{
query = query.Where(x => x.YearManufactured <= currentYear - 70);
}
else if (Utility.EqualsIgnoringOrder(values, new List<int> { 1, 2}))
{
query = query.Where(x => x.YearManufactured >= currentYear - 20);
}
else if (Utility.EqualsIgnoringOrder(values, new List<int> { 1, 3 }))
{
query = query.Where(x => x.YearManufactured >= currentYear - 10 || (x.YearManufactured <= currentYear - 20 && x.YearManufactured >= currentYear - 70));
}
else if (Utility.EqualsIgnoringOrder(values, new List<int> { 1, 4 }))
{
query = query.Where(x => x.YearManufactured >= currentYear - 10 || x.YearManufactured <= currentYear - 70);
}
else if (Utility.EqualsIgnoringOrder(values, new List<int> { 2, 3 }))
{
query = query.Where(x => x.YearManufactured <= currentYear - 10 && x.YearManufactured >= currentYear - 70);
}
else if (Utility.EqualsIgnoringOrder(values, new List<int> { 2, 4 }))
{
query = query.Where(x => (x.YearManufactured <= currentYear - 10 && x.YearManufactured >= currentYear - 20)
|| x.YearManufactured <= currentYear - 70);
}
else if (Utility.EqualsIgnoringOrder(values, new List<int> { 1, 2, 3 }))
{
query = query.Where(x => x.YearManufactured >= currentYear - 70);
}
else if (Utility.EqualsIgnoringOrder(values, new List<int> { 1, 2, 4 }))
{
query = query.Where(x => x.YearManufactured >= currentYear - 20 || x.YearManufactured <= currentYear - 70);
}
else if (Utility.EqualsIgnoringOrder(values, new List<int> { 2, 3, 4}))
{
query = query.Where(x => x.YearManufactured <= currentYear - 10);
}
else if (Utility.EqualsIgnoringOrder(values, new List<int> { 1, 3, 4}))
{
query = query.Where(x => x.YearManufactured >= currentYear - 10 || x.YearManufactured <= 20);
}
else if (Utility.EqualsIgnoringOrder(values, new List<int> { 1, 2, 3, 4 }))
{
// all
}
return query;
}
}