Il "più popolare" GROUP BY in LINQ?
Domanda
Supponendo una tabella di tag come i tag di domanda stackoverflow:
TagID (bigint), QuestionID (bigint), Tag (varchar)
Qual è il modo più efficiente per ottenere i 25 tag più utilizzati usando LINQ? In SQL, un semplice GROUP BY farà:
SELECT Tag, COUNT(Tag) FROM Tags GROUP BY Tag
Ho scritto alcuni LINQ che funzionano:
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);
Come, davvero? Questo mega-verbose non è? La cosa triste è che lo sto facendo per salvare un numero enorme di query, poiché i miei oggetti Tag contengono già una proprietà Frequenza che altrimenti avrebbe bisogno di ricontrollare con il database per ogni Tag se effettivamente avessi usato la proprietà.
Quindi analizzo questi tipi anonimi indietro in oggetti Tag:
groups.OrderByDescending(g => g.Frequency).Take(25).ToList().ForEach(t => tags.Add(new Tag()
{
Tag = t.Tag,
Frequency = t.Frequency
}));
Sono un principiante di LINQ e questo non sembra giusto. Per favore, mostrami come è stato fatto.
Soluzione
Sono abbastanza sicuro che tu abbia capito bene. Inoltre, l'SQL che LINQ genera e invierà al tuo db sarà simile all'SQL con cui hai iniziato, quindi mentre stai scrivendo un po 'di più, il tuo database non sta facendo altro lavoro.
Altri suggerimenti
Se vuoi oggetti Tag, perché non crearli direttamente dalla tua query 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);
Se si utilizza la forma dettagliata della sintassi, il codice sarà dettagliato. Ecco un'alternativa:
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();
Penso che tu sia anche ingiusto in quanto la tua query SQL non fa la stessa cosa della tua query LINQ - non restituisce la top 25.