"Самый популярный" GROUP BY в LINQ? - PullRequest
30 голосов
/ 30 октября 2008

Принимая таблицу тегов, таких как теги вопроса stackoverflow:

TagID (bigint), QuestionID (bigint), Tag (varchar)

Как наиболее эффективно получить 25 наиболее часто используемых тегов с помощью LINQ? В SQL простой GROUP BY будет делать:

SELECT Tag, COUNT(Tag) FROM Tags GROUP BY Tag

Я написал LINQ, который работает:

var groups = from t in DataContext.Tags
             group t by t.Tag into g
             select new { Tag = g.Key, Frequency = g.Count() };
return groups.OrderByDescending(g => g.Frequency).Take(25);

Как, правда? Разве это не мега многословно? Печально то, что я делаю это, чтобы сохранить огромное количество запросов, поскольку мои объекты Tag уже содержат свойство Frequency, которое в противном случае потребовало бы проверки в базе данных для каждого тега, если бы я действительно использовал это свойство.

Итак, я анализирую эти анонимные типы back в объекты Tag:

groups.OrderByDescending(g => g.Frequency).Take(25).ToList().ForEach(t => tags.Add(new Tag()
{
    Tag = t.Tag,
    Frequency = t.Frequency
}));

Я новичок в LINQ, и это не так. Пожалуйста, покажите мне, как это действительно делается.

Ответы [ 4 ]

24 голосов
/ 30 октября 2008

Если вам нужны объекты Tag, почему бы не создать их непосредственно из запроса Linq?

var groups = from t in DataContext.Tags
             group t by t.Tag into g
             select new Tag() { Tag = g.Key, Frequency = g.Count() };

return groups.OrderByDescending(g => g.Frequency).Take(25);
12 голосов
/ 30 октября 2008

Если вы используете подробную форму синтаксиса, ваш код будет подробным. Вот альтернатива:

List<Tag> result = 
  db.Tags
  .GroupBy(t => t.Tag)
  .Select(g => new {Tag = g.Key, Frequency = g.Count()})
  .OrderByDescending(t => t.Frequency)
  .Take(25)
  .ToList()
  .Select(t => new Tag(){Tag = t.Tag, Frequency = t.Frequency})
  .ToList();
10 голосов
/ 30 октября 2008

Я почти уверен, что вы правильно поняли. Кроме того, SQL, который LINQ генерирует и отправляет в вашу базу данных, будет выглядеть так же, как SQL, с которого вы начали, поэтому, пока вы немного больше печатаете, ваша база данных больше не работает.

3 голосов
/ 21 мая 2010

Я думаю, что вы также несправедливы в том, что ваш запрос SQL не выполняет то же самое, что ваш запрос LINQ - он не возвращает верхний 25.

...