2015-10-20 37 views
1

我想建立一個查詢,我根據主題過濾新聞。每個新聞都可以有幾個主題。當我過濾時,我希望得到每個具有我過濾的主題的新聞,但我得到的是具有我選擇的所有主題的新聞項目。建設查詢過濾條件或條件

我已經嘗試過不同的解決方案,這裏是我現在擁有的東西。有任何想法嗎?

IQueryable<News> news = context.News; 

if (themes.Any()) 
{ 
    foreach (var t in themes) 
    { 
    news = news.Where(n => n.Post.Themes.Count > 0).Where(n => n.Post.Themes.Select(th => th.Id).Contains(t.Id)); 
    } 
} 
return news.ToList(); 
+1

什麼或沒有按」這樣做嗎? – CodeCaster

+0

如果我選擇主題A和B,則只返回具有A和B主題的新聞。我想要所有具有主題A或B或兩者的新聞。 –

回答

1

你可以得到的主題ID添加到陣列,並把它傳遞給包含extention

IQueryable<News> news = context.News; 
var themesIds = themes.Select(t=>t.Id).ToArray(); 

news = news.Where(n => n.Post.Themes.Any(t=>themesIds.Contains(t.Id))); 

return news.ToList(); 
+0

非常感謝你,這工作完美! –

1

試圖聲明themesHasSet,並使用一個查詢:

news.Where(n => n.Post.Themes.Any(t => themes.Contains(t))) 

UPDATE:我們不需要這裏的HashSet。數組足夠好。謝謝@KingKing和@Dennis

+0

爲什麼'HashSet'?使用數組就足夠了。 – Dennis

+0

HashSet.Contains的計算複雜性是O(1),但Array.Contains是O(n) – Alexander

+1

在*** LinqToObject ***這是true,但實際上這裏查詢被轉換爲SQL查詢,我不認爲這裏是本地計算的一個好處。在這種情況下,Array或HashSet應該是相同的。我們可以查看生成的sql查詢來更好地理解它(兩者都應該生成相同的sql查詢)。 –

0

你可以爲你的News類寫一個擴展方法。

public static class NewsExtensions { 

public static List<News> GetNewsByTheme(this List<News> news, List<Theme> themes) { 
    List<News> result = new List<News>(); 
    foreach(var theme in themes) { 
     foreach(var newsItem in news) { 
      ...some logic here 
      result.Add(newsItem); 
     } 
    } 
    return result; 
} 

然後在你的代碼只要致電:基於您的代碼

List<News> newsContainingThemes = news.GetNewsByTheme(themes);