开发者

Counting in a Many-To-Many Relationship in Entity Framework

Using Entity Framework 4.1 Code First I have two objects with a many-to-many relationship:

 public开发者_运维问答 class Article  
    {
        public int ID { get; set; } 
        public string Title { get; set; } 
        public string Description { get; set; }
        public ICollection<Tag>  Tags { get; set; }
}

 public class Tag
        { 
            [Key]
            public string UrlSlug { get; set; }
            public string Name { get; set; }
            public ICollection<Article> Articles { get; set; }
}

I want to count the most common Tags applied to Articles. How do I do this in LINQ?

I tried the below code which only ordered the Tags:

  var tagsFromDb = db.Tags
                  .GroupBy(q => q.UrlSlug)
                  .OrderByDescending(gp => gp.Count())
                  .Select(g => g.FirstOrDefault());


If I understand right you have a many-to-many relationship between articles and tags but the navigation property on the tag side is not exposed (there is no ICollection<Article> in Tag). I think in this case you have to start from the articles to get all used tags along with the information how often they are used in the articles:

var tagQuery = db.Articles
    .SelectMany(a => a.Tags)          // flat enumeration of all used tags
    .GroupBy(t => t, (k, g) => new    // k = key = Tag, g = group of same tags
    {
        Tag = k,                      // the tag
        Count = g.Count()             // how often does it occur in the articles
    })
    .OrderByDescending(g => g.Count); // most used tags first

If you want all tags sorted descending, call

var tagList = tagQuery.ToList();

If you just want the tag which is most often used in the articles, call

var mostUsedTag = tagQuery.FirstOrDefault();

In both cases the result is a collection/single object of an anonymous type which has the Tag and Count as members. If you just want the tag(s) and are not interested in the Count anymore you can project before apply ToList or FirstOrDefault: tagQuery.Select(anonymous => anonymous.Tag).....

Edit

Just saw the Edit in your question. Now, when you have an Article collection in the Tag entity it is easier:

var tagQuery = db.Tags
    .Select(t => new
    {
        Tag = t,                      // the Tag
        Count = t.Articles.Count()    // just count the number of artices
                                      // the tag is used in
    })
    .OrderByDescending(x => x.Count); // most used tags first
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜