2015-10-20 80 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);