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
精彩评论