Вопрос

Предполагая таблицу тегов, таких как теги вопроса 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, и это не так. Пожалуйста, покажи мне, как это действительно делается.

Это было полезно?

Решение

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

Другие советы

Если вам нужны объекты 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);

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

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();

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top