Выбор связанной статьи на основе общих тегов в Entity Framework - PullRequest
0 голосов
/ 16 марта 2012

У меня есть следующие объекты:

public class Article {
    public int Id { get; set; }
    public virtual IList<Tag> Tags { get; set; }
}

public class Tag {
    public int Id { get; set; }
    public virtual IList<Article> Articles { get; set; }
}

Я загружаю Article на Tag s следующим образом:

var articleByTags = context.Articles.Include(a => a.Tags).FirstOrDefault(a => a.Id == someId);

Теперь, как я могу получить список статей, которые должны иметь общие теги с выбранной статьей? Не могли бы вы мне помочь?

Ответы [ 2 ]

2 голосов
/ 16 марта 2012

Хороший вопрос. Вот решение:

// you should have a list of primitive types to use in SQL IN keyword
var ids = articleByTags.Tags.Select(t => t.Id).ToList();
var query = (from article in context.Articles
              // do you want same article again? NO! so remove the current article
             where article.Id != articleByTags.Id
             // this line would create a IN statement to SQL
             // if you don't want to load common tags, you can merge this line
             // by the next it, and just create a COUNT()
             let commonTags = article.Tags.Where(tag => ids.Contains(tag.Id))
             let commonCount = commonTags.Count()
             // there as any?
             where commonCount > 0
             // ascending! not descending! you want most common 
             orderby commonCount ascending
             // create your projection
             select new {
                 Id = article.Id,
                 Title = article.Title,
                 Tags = article.Tags,
                 Commons = commonTags,
                 CommonCount = commonCount
                 // or any property you want...
            })
            // how many you want to take? for example 5
            .Take(5)
            .ToList();
0 голосов
/ 16 марта 2012

Я думаю, вы хотите что-то вроде этого:

var listOfMustHaveTags = new List<Tag>(); // Should be filled with Tags
var articleByCommonTags = context.Articles.Where(n => n.Tags.All(listOfMustHaveTags.Contains));

Если требование гласит, что должен соответствовать хотя бы один тег, то замените .All() на .Any().

...