2016-08-16 37 views
2

想知道是否存在針對這種複雜情況的linq解決方案;例如,客戶選擇顏色:紅色,尺寸:大,類型:棉花。如果我知道肯定是一個客戶會選擇這些過濾器每單的時候,我只想做這樣的事情:構建基於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(); 
       } 
      } 
    } 
+1

你的問題,基本上,如何構建一個表達式根據其名稱訪問該屬性? – Groo

+2

如果不爲您編寫它,請查看錶達式樹:https://msdn.microsoft.com/en-us/library/mt654263.aspx,這是更優雅的方法之一。否則,只要在你的where子句中進行演繹推理。 – RandomUs1r

+0

*如果我確實知道客戶每次都會選擇這些過濾器,我只會做這樣的事情*好的,這有什麼問題?我期待的是,*但是... * –

回答

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"} 
+1

剛剛有機會嘗試這種方法,它看起來很有前途;但是,在同時選擇屬於不同濾鏡的值時,它效果不佳。例如,如果我想選擇顏色紅色,那麼選擇棉花類型,我最終只能選擇棉花類型...等 – usefulBee

+1

我編輯了代碼並在每個「過濾器集合」周圍添加了括號。似乎沒有他們,其他過濾器未經驗證。 – jtmnt

+0

剛剛嘗試過編輯後的代碼,它似乎沒有工作,因爲它將返回所有項目而不管任何過濾器。 – usefulBee

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可以消除,但是,似乎是大材小用爲您的使用情況。

+0

優秀的方法和運作良好。但是,我想知道如何調整它以使其成爲還原過濾方法?這意味着選擇「紅色」和「後來的棉花」會帶來「僅限」棉花型紅色襯衫。到目前爲止,這種方法帶來了所有紅色襯衫和所有棉花襯衫 – usefulBee

+1

@usefulBee啊,我誤解了你的問題。給我更新的答案一個旋轉,看看它是否滿足你的需求。 –

+0

我驗證了更新後的答案,它的作用像魅力!僅僅因爲它的清晰性,將答案授予另一種方法是一個艱難的決定;不過,我真的很感謝你與其他人分享你的頂尖技能和四維思維。請不要停下! – usefulBee