想知道是否有针对这种复杂情况的linq解决方案;例如,客户选择颜色:红色,尺寸:大,类型:棉花。如果我确定客户每次都会选择这些过滤器,我会做这样的事情:
var shirts = ListOfShirts.Where(i=> i.Color.Contains("red") && Size.Contains("Large") && Type.Contains("Cotton"));
以下是当前结构和一个从视图中接受大量过滤器的操作方法:
类:
public partial class Shirt {
public long ID { get; set; }
public string Color { get; set; }
public string Size { get; set; }
public string Type { get; set; }
}
public class SelectedFilter {
public string Name { get; set; } // Filter Menu Title
public string Value { get; set; }
}
控制器:
public ActionResult Filter(IList<SelectedFilter> selectedFilters) {
var model = new List<Shirt>();
Shirt ListOfShirts = db.GetAllShirts();
var groups = selectedFilters.GroupBy(i => i.Name);
foreach (var g in groups)
{
var GroupName = g.FirstOrDefault().name;
var GroupValues = g.Select(i => i.value).ToList();
if (g.FirstOrDefault().name == "Color")
{
model = ListOfShirts.Where(i => GroupValues.Contains(i.Color)).ToList();
}
else if (g.FirstOrDefault().name == "Size")
{
model = ListOfShirts.Where(i => GroupValues.Contains(i.Size)).ToList();
}
else if (g.FirstOrDefault().name == "Type")
{
model = ListOfShirts.Where(i => GroupValues.Contains(i.Type)).ToList();
}
}
}
答案 0 :(得分:1)
您可以编写一个方法来检查给定的Shirt
是否在过滤器中,然后使用All
检查每个过滤器。
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;
}
}
如果您想使用反射访问属性,switch
可以被删除,但这对您的用例来说似乎有些过分。
答案 1 :(得分:1)
一种(野蛮)方式:
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();
}
如果您有多个具有相同名称的过滤器值
,这也应该有效{Name="Color",Value="Red"},{Name="Color",Value="Blue"}