.net - groupby - "Más popular" GROUP BY en LINQ?
linq to sql group by (4)
Estoy bastante seguro de que lo tienes bien. Y, el SQL que LINQ genera y enviará a su base de datos se verá igual que el SQL con el que comenzó, por lo que mientras está escribiendo un poco más, su base de datos no está haciendo más trabajo.
Suponiendo una tabla de etiquetas como las etiquetas de pregunta stackoverflow:
TagID (bigint), QuestionID (bigint), Tag (varchar)
¿Cuál es la forma más eficiente de obtener las 25 etiquetas más usadas con LINQ? En SQL, un simple GROUP BY hará:
SELECT Tag, COUNT(Tag) FROM Tags GROUP BY Tag
He escrito algunos LINQ que funcionan:
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);
¿Como realmente? ¿No es esto mega verboso? Lo triste es que estoy haciendo esto para ahorrar una gran cantidad de consultas, ya que mis objetos Tag ya contienen una propiedad Frequency que de otra manera tendría que volver a consultar con la base de datos para cada etiqueta si realmente utilizo la propiedad.
Entonces, vuelvo a analizar estos tipos anónimos en objetos Tag:
groups.OrderByDescending(g => g.Frequency).Take(25).ToList().ForEach(t => tags.Add(new Tag()
{
Tag = t.Tag,
Frequency = t.Frequency
}));
Soy un novato LINQ, y esto no parece correcto. Por favor muéstrame cómo se hace realmente.
Si desea objetos Tag, ¿por qué no crearlos directamente desde su consulta 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);
Si usa la forma detallada de la sintaxis, su código será detallado. Aquí hay una 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();
Creo que también es injusto que su consulta SQL no haga lo mismo que su consulta LINQ; no devuelve los 25 primeros.