在实体框架中计算多对多关系

时间:2011-09-17 10:18:45

标签: linq entity-framework

使用Entity Framework 4.1 Code First我有两个具有多对多关系的对象:

 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; }
}

我想计算应用于文章的最常见标签。我如何在LINQ中执行此操作?

我尝试了以下代码,只订购了标签:

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

1 个答案:

答案 0 :(得分:3)

如果我理解正确,您在文章和标签之间存在多对多关系,但标签面上的导航属性未公开(ICollection<Article>中没有Tag)。我认为在这种情况下,您必须从文章开始,以获取所有使用的标签以及信息在文章中使用的频率:

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

如果您希望所有标签按降序排序,请致电

var tagList = tagQuery.ToList();

如果您只想要文章中最常用的标签,请致电

var mostUsedTag = tagQuery.FirstOrDefault();

在这两种情况下,结果都是匿名类型的集合/单个对象,其中TagCount为成员。如果您只是想要标记并且对Count不感兴趣,则可以在应用ToListFirstOrDefault之前进行投射:tagQuery.Select(anonymous => anonymous.Tag)....

修改

刚看到你问题中的编辑。现在,如果Article实体中有Tag个集合,则更容易:

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