0

我有这些实体:

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我通过它的 s加载一个,Tag如下所示:

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

现在,我怎样才能获得与所选文章有共同标签的文章列表?你能帮我吗?

4

2 回答 2

1

好问题。这是解决方案:

// 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();
于 2012-03-16T09:48:55.627 回答
0

我想你想要这样的东西:

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

如果要求要求至少有一个标签必须适合,则更.All()改为.Any().

于 2012-03-16T09:08:38.310 回答