Matching two enumerations of strings in a LINQ-query
I have 3 classes (simplified for this question):
public class Page
{
public Guid PageUid;
public string PageTitle;
public IQueryable<Keyword> Keywords;
}
public class News
public Guid NewsUid;
public string NewsTitle;
public IQueryable<Keyword> Keywords;
}
public class Keyword
public Guid KeywordUid;
public string KeywordTitle;
}
I want to list all news-entries on a page where all (not any) keywords of this page matches with some or all of the keywords of the news. The page should display only news, where all the keywords of the page are present in the news. If one of the keywords of the page is not present in a news, this entry should not be displayed. But if the news-entry has more keywords than the page, the news should be displayed – if the keywords of the page are also present in the list of keywords of this news-item. If not, than the news should of course not be listed.
Quite complicated to explain, i try to sketch a real-life-example for better understanding:
Example:
The definitions are:
- PageA has 1 keyword: Kw1
- PageB has 2 keywords: Kw1, Kw2
- PageC has 2 keywords: Kw1, Kw3
- PageD has 3 keywords: Kw1, Kw2, Kw3
- NewsW has 1 keyword: Kw1
- NewsX has 2 keywords: Kw1, Kw2
- NewsY has 2 keywords: Kw1, Kw3
- NewsZ has 3 keywords: Kw1, Kw2, Kw4
The results should be:
- PageA displays 4 items: NewsW, NewsX, NewsY, NewsZ
- PageB lists 2 news: NewsX, NewsZ
- PageC shows only 1 entry: NewsY
- PageD has not even one match.
The 'linking' element is the string开发者_如何学C 'KeywordTitle' and not the Guid 'KeywordGuid' or just the 'Keyword'-object, because keywords should match if just the title (string) is identical.
In reality the 3 classes are tables in a database. I connect to the database with EntityFramework. The language is C#. The project is a ASP.NET MVC 3 Website.
The solution for my problem should be a LINQ-query if possible.
I hope someone has a solution for this – i tried so many different things, but had no success.
Thanks in advance for your help.
DanielD
IEnumerable<News> news = …;
Page page = …;
var newsOnPage = news.Where(n => page.Keywords.All(pk => n.Keywords.Contains(pk)));
This assumes comparing keywords by the default comparer works as expected.
The intersection of news keywords and page keywords must result in all page keywords. All page keywords must appear in news keywords. I had a similar situation and here is how I did it.
if (ANews.Keywords.Intersect(APage.Keywords).Count() == APage.Keywords.Count())
{
// Display news.
}
精彩评论