2013-04-14 134 views
3

我在使用LINQ進行概念化應該相當簡單。基於子對象的id值,我想要縮小或過濾一個集合。LINQ查詢按多個列表中的條件篩選項目

我的主要集合包含一個點列表。這是一個現貨看起來像:

public class Spot 
{ 
    public virtual int? ID { get; set; } 
    public virtual string Name { get; set; } 
    public virtual string Description { get; set; } 
    public virtual string TheGood { get; set; } 
    public virtual string TheBad { get; set; } 
    public virtual IEnumerable<Season> Seasons { get; set; } 
    public virtual IEnumerable<PhotographyType> PhotographyTypes { get; set; } 
} 

我想過濾的攝影類型和季節點的列表。我有一個用於PhotographyTypes和Seasons的ID列表,每個都在一個int []數組中。這些清單是這樣的:

criteria.PhotographyTypeIds //an int[] 
criteria.SeasonIds //an int[] 

我想建立一個集合,只包含與子對象(IDS)景點符合這些在上面的列表中。此功能的目標是根據類型和季節過濾一組攝影點,並僅顯示匹配的那些點。任何建議將不勝感激。

回答

0

這可能幫助你:

List<Spot> spots = new List<Spot>(); 
Spot s1 = new Spot(); 
s1.Seasons = new List<Season>() 
      { new Season() { ID = 1 }, 
       new Season() { ID = 2 }, 
       new Season() { ID = 3 } 
      }; 
s1.PhotographyTypes = new List<PhotographyType>() 
      { new PhotographyType() { ID = 1 }, 
       new PhotographyType() { ID = 2 } 
      }; 

Spot s2 = new Spot(); 
s2.Seasons = new List<Season>() 
      { new Season() { ID = 3 }, 
       new Season() { ID = 4 }, 
       new Season() { ID = 5 } 
      }; 
s2.PhotographyTypes = new List<PhotographyType>() 
      { new PhotographyType() { ID = 2 }, 
       new PhotographyType() { ID = 3 } 
      }; 

List<int> PhotographyTypeIds = new List<int>() { 1, 2}; 
List<int> SeasonIds = new List<int>() { 1, 2, 3, 4 }; 

spots.Add(s1); 
spots.Add(s2); 

然後:

var result = spots 
      .Where(input => input.Seasons.All 
          (i => SeasonIds.Contains(i.ID)) 
        && input.PhotographyTypes.All 
          (j => PhotographyTypeIds.Contains(j.ID)) 
        ).ToList(); 
// it will return 1 value 

假設:

public class Season 
{ 
    public int ID { get; set; } 
    //some codes 
} 
public class PhotographyType 
{ 
    public int ID { get; set; } 
    //some codes 
} 
+0

轉換INT後[]列出(所以可以使用。載有()),並嘗試了這一點,它的每一次返回任何內容。 –

+0

@DonFitz如果它不能解決你的問題,讓我知道,所以我可以刪除我的答案。 –

0

你有一組ID具有Contains擴展方法,將返回true當ID在列表中時。與LINQ Where相結合,你會得到:

List<Spot> spots; // List of spots 
int[] seasonIDs; // List of season IDs 

var seasonSpots = from s in spots 
        where s.ID != null 
        where seasonIDs.Contains((int)s.ID) 
        select s; 

然後,您可以轉換返回IEnumerable<Spot>到列表中,如果你想:

var seasonSpotsList = seasonSpots.ToList(); 
1

感謝大家的建議。我最終解決了這個問題。這不是我確定的最好方式,但它現在正在工作。因爲這是一個搜索過濾器,所以有很多條件。

private List<Spot> FilterSpots(List<Spot> spots, SearchCriteriaModel criteria) 
    { 
     if (criteria.PhotographyTypeIds != null || criteria.SeasonIds != null) 
     { 
      List<Spot> filteredSpots = new List<Spot>(); 

      if (criteria.PhotographyTypeIds != null) 
      { 
       foreach (int id in criteria.PhotographyTypeIds) 
       { 
        var matchingSpots = spots.Where(x => x.PhotographyTypes.Any(p => p.ID == id)); 
        filteredSpots.AddRange(matchingSpots.ToList()); 
       } 
      } 

      if (criteria.SeasonIds != null) 
      { 
       foreach (int id in criteria.SeasonIds) 
       { 
        if (filteredSpots.Count() > 0) 
        { 
         filteredSpots = filteredSpots.Where(x => x.Seasons.Any(p => p.ID == id)).ToList(); 
        } 
        else 
        { 
         var matchingSpots = spots.Where(x => x.Seasons.Any(p => p.ID == id)); 
         filteredSpots.AddRange(matchingSpots.ToList()); 
        } 
       } 
      } 
      return filteredSpots; 
     } 
     else 
     { 
      return spots; 
     } 
    }