Cómo seleccionar solo los registros con la fecha más alta en LINQ

117

Tengo una tabla, 'lasttraces', con los siguientes campos.

Id, AccountId, Version, DownloadNo, Date

Los datos se ven así:

28092|15240000|1.0.7.1782|2009040004731|2009-01-20 13:10:22.000
28094|61615000|1.0.7.1782|2009040007696|2009-01-20 13:11:38.000
28095|95317000|1.0.7.1782|2009040007695|2009-01-20 13:10:18.000
28101|15240000|1.0.7.1782|2009040004740|2009-01-20 14:10:22.000
28103|61615000|1.0.7.1782|2009040007690|2009-01-20 14:11:38.000
28104|95317000|1.0.7.1782|2009040007710|2009-01-20 14:10:18.000

¿Cómo puedo, en LINQ to SQL , obtener solo el último rastro de cada AccountId (el que tiene la fecha más alta)?

Bas Jansen
fuente
en realidad, en su ejemplo, todos los registros con la misma identificación de cuenta, tienen exactamente la misma fecha, entonces, ¿cuál tiene preferencia en ese caso?
BlackTigerX

Respuestas:

230

Si solo desea la última fecha para cada cuenta, usaría esto:

var q = from n in table
        group n by n.AccountId into g
        select new {AccountId = g.Key, Date = g.Max(t=>t.Date)};

Si quieres el registro completo:

var q = from n in table
        group n by n.AccountId into g
        select g.OrderByDescending(t=>t.Date).FirstOrDefault();
Mehrdad Afshari
fuente
2
Oracle no admite esto. Si el rendimiento de la consulta está fuera de su consideración, puede convertir la tabla en Lista antes de realizar la consulta.
Will Wu
8
Sería genial si pudiera publicar una method-chainsolución para esto.
LCJ
segunda consulta, ¿no debería ser así (from n in table ...).First()?
Jason L
@JasonL, no. La First()llamada debe aplicarse a la g.Order...expresión (subconsulta).
Mehrdad Afshari
1
@Mehrdad Afshari eso es increíble , quería el segundo principalmente, pero ambos están ahora en mis fragmentos, ya que son muy útiles . ¡¡¡¡¡Gracias, gracias, gracias!!!!!
Andrew Day
52

Aquí tienes una forma sencilla de hacerlo

var lastPlayerControlCommand = this.ObjectContext.PlayerControlCommands
                                .Where(c => c.PlayerID == player.ID)
                                .OrderByDescending(t=>t.CreationTime)
                                .FirstOrDefault();

También eche un vistazo a este gran lugar de LINQ : ejemplos de LINQ to SQL

Desarrollador
fuente
25
Esta solución funciona bien si estaba consultando por cuenta pero no hace lo que OP indicó, que es obtener el resultado más reciente para todos los registros sin proporcionar un AccountId (en su caso, PlayerId)
Maciej
1
Esta solución me inspiró a ordenar en su lugar para intentar seleccionar el máximo. +1
Razvan Dumitru
Esta solución puede llevar al error "La secuencia no contiene elementos" en Linq, ¿verdad?
xSkrappy
34

Si desea el registro completo, aquí hay una forma lambda:

var q = _context
             .lasttraces
             .GroupBy(s => s.AccountId)
             .Select(s => s.OrderByDescending(x => x.Date).FirstOrDefault());
Bob Zhang
fuente
1
Funcionó muy bien. Gracias.
Terry
Esta es la clave aquí.
Jason P Sallinger
5

Podría ser algo como:

var qry = from t in db.Lasttraces
          group t by t.AccountId into g
          orderby t.Date
          select new { g.AccountId, Date = g.Max(e => e.Date) };
bruno conde
fuente
3

Vaya a una forma sencilla de hacer esto: -

Creó una clase para contener la siguiente información

  • Nivel (número)
  • Url (URL del sitio)

Vaya a la lista de sitios almacenados en un objeto ArrayList. Y ejecutó la siguiente consulta para ordenarla en orden descendente por Nivel.

var query = from MyClass object in objCollection 
    orderby object.Level descending 
    select object

Una vez que obtuve la colección ordenada en orden descendente, escribí el siguiente código para obtener el Objeto que viene como fila superior

MyClass topObject = query.FirstRow<MyClass>()

Esto funcionó a las mil maravillas.

Sudhir Kesharwani
fuente
Esto me dio una idea mejor que mi pensamiento original. ¡Gracias!
Paulj