Подсчет в отношениях «многие ко многим» в структуре сущностей - PullRequest
2 голосов
/ 17 сентября 2011

Использование Entity Framework 4.1 Code Сначала у меня есть два объекта с отношением «многие ко многим»:

 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 Ответ

3 голосов
/ 17 сентября 2011

Если я правильно понимаю, у вас есть отношение многие ко многим между статьями и тегами, но свойство навигации на стороне тега не отображается (нет 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();

В обоих случаях результатом является коллекция / отдельный объект анонимного типа, в котором Tag и Count являются членами. Если вам нужны только теги и вы больше не заинтересованы в Count, вы можете проецировать его перед применением ToList или FirstOrDefault: tagQuery.Select(anonymous => anonymous.Tag).....

Редактировать

Только что увидел Edit в вашем вопросе. Теперь, когда у вас есть 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...