2011-02-16 12 views
5

Tiene que haber un trazador de líneas para hacer esto, y simplemente no puedo encontrarlo.Agrupe los elementos y seleccione elementos específicos de cada grupo con LINQ

Teniendo en cuenta esta consulta:

from x in new XPQuery<XPContent>(s) 
select new { x.Category, x.ContentType, x.Name, x.ContentID, x.Date } 

necesito para seleccionar el registro con la fecha grande para cada ContentID distinta. ¿Se puede hacer esto inteligentemente con LINQ? En este momento estoy haciendo esto:

var q = (from x in new XPQuery<XPContent>(s) 
      select new { x.Category, x.ContentType, x.Name, x.ContentID, x.Date }).ToList(); 

var r = q.ToLookup(item => item.ContentID); 
foreach (var rItem in r) { 
    var s = rItem.OrderByDescending(a => a.Date).First(); 
    /* do stuff with s */ 
} 

... pero el ToLookup se siente un poco torpe. ¿O tengo la mejor solución (la más simple)?

Además, sé que no debería usar ToList, pero ignórelo por el momento.

¡Gracias de antemano!

Respuesta

6

Creo que desee:

var q = from x in new XPQuery<XPContent>(s) 
     group x by x.ContentID into g 
     let latest = g.OrderByDescending(a => a.Date).First() 
     select new 
     { 
      latest.Category, latest.ContentType, 
      latest.Name, latest.ContentID, latest.Date 
     }; 

(. Ten en cuenta que hay formas más performant de encontrar el elemento 'máximo' de un grupo de por clasificarlos en primer lugar, por ejemplo, con un operador de MaxBy)

La consulta es bastante simple; simplemente agrupa los elementos por su ContentId, y luego de cada grupo, selecciona una instancia de un tipo anónimo que se produce a partir del último elemento del grupo.

+2

Nunca he sabido de 'dejar' - gracias! –

Cuestiones relacionadas