¿Cómo obtengo la fila MAX con un GROUP BY en la consulta LINQ?

94

Estoy buscando una forma en LINQ para que coincida con la siguiente consulta SQL.

Select max(uid) as uid, Serial_Number from Table Group BY Serial_Number

Realmente estoy buscando ayuda en este caso. La consulta anterior obtiene el uid máximo de cada número de serie debido a la Group Bysintaxis.

SpoiledTechie.com
fuente

Respuestas:

92
        using (DataContext dc = new DataContext())
        {
            var q = from t in dc.TableTests
                    group t by t.SerialNumber
                        into g
                        select new
                        {
                            SerialNumber = g.Key,
                            uid = (from t2 in g select t2.uid).Max()
                        };
        }
tvanfosson
fuente
1
Quiero aceptar ambas como respuestas, pero supongo que no puedo, así que voté por ustedes dos. ¡¡¡Gracias un montón!!!
SpoiledTechie.com
69
var q = from s in db.Serials
        group s by s.Serial_Number into g
        select new {Serial_Number = g.Key, MaxUid = g.Max(s => s.uid) }
DamienG
fuente
Quiero aceptar ambas como respuestas, pero supongo que no puedo, así que voté por ustedes dos. ¡¡¡Gracias un montón!!!
SpoiledTechie.com
También tenga en cuenta que la variable para la expresión => lambda en la función Max puede ser cualquier cosa (s => s.uid, tv => tv.uid, asdf => asdf.uid). Linq reconocerá automáticamente que selecciona elementos de tipo Serial.
Michael
30

En forma de cadena de métodos:

db.Serials.GroupBy(i => i.Serial_Number).Select(g => new
    {
        Serial_Number = g.Key,
        uid = g.Max(row => row.uid)
    });
Lu55
fuente
22

Revisé la respuesta de DamienG en LinqPad. En vez de

g.Group.Max(s => s.uid)

debiera ser

g.Max(s => s.uid)

¡Gracias!

denis_n
fuente
10
Esto probablemente debería ser un comentario sobre la respuesta de DamienG.
Cᴏʀʏ
10

Las respuestas están bien si solo necesita esos dos campos, pero para un objeto más complejo, tal vez este enfoque podría ser útil:

from x in db.Serials 
group x by x.Serial_Number into g 
orderby g.Key 
select g.OrderByDescending(z => z.uid)
.FirstOrDefault()

... esto evitará el "seleccionar nuevo"

Javier
fuente
Me gusta esto, ¿sabes si es tan eficiente como las otras respuestas?
noelicus
Usó la sintaxis de consulta aquí hasta el final, donde cambió a la sintaxis del método. ¿Tenias que? ¿Es el formulario de sintaxis de consulta completo para su solución?
Seth
0

Esto se puede hacer usando GroupBy y SelectMany en la expresión LINQ lamda

var groupByMax = list.GroupBy(x=>x.item1).SelectMany(y=>y.Where(z=>z.item2 == y.Max(i=>i.item2)));
Abhas Bhoi
fuente