Comment sélectionner uniquement les enregistrements avec la date la plus élevée dans LINQ


117

J'ai une table, «lasttraces», avec les champs suivants.

Id, AccountId, Version, DownloadNo, Date

Les données ressemblent à ceci:

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

Comment puis-je, dans LINQ to SQL , obtenir uniquement la dernière trace de chaque AccountId (celui avec la date la plus élevée)?


En fait, dans votre exemple, tous les journaux avec le même identifiant de compte ont exactement la même date, alors lequel a la préférence dans ce cas?
BlackTigerX

Réponses:


231

Si vous voulez juste la dernière date pour chaque compte, vous utiliserez ceci:

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 vous voulez l'intégralité de l'enregistrement:

var q = from n in table
        group n by n.AccountId into g
        select g.OrderByDescending(t=>t.Date).FirstOrDefault();

2
Oracle ne prend pas en charge cela. Si les performances des requêtes ne sont pas prises en compte, vous pouvez convertir la table ToList avant d'effectuer la requête.
Will Wu

8
Ce serait formidable si vous pouviez publier une method-chainsolution pour cela.
LCJ

deuxième question - ne devrait-il pas être (from n in table ...).First()?
Jason L

@JasonL, non. L' First()appel doit s'appliquer à l' g.Order...expression (sous-requête).
Mehrdad Afshari

1
@Mehrdad Afshari c'est incroyable , je voulais principalement le second, mais ils sont tous les deux maintenant dans mes extraits comme très utiles . Merci merci merci!!!!!
Andrew Day

52

Voici un moyen simple de le faire

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

Jetez également un œil à cet excellent endroit LINQ - Exemples LINQ to SQL


25
Cette solution fonctionne très bien si vous interrogiez par compte mais ne fait pas ce que OP a déclaré, qui est d'obtenir le résultat le plus récent pour tous les enregistrements sans fournir un AccountId (dans votre cas PlayerId)
Maciej

1
Cette solution m'a inspiré à commander plutôt pour essayer de sélectionner le maximum. +1
Razvan Dumitru

Cette solution peut conduire à une erreur "La séquence ne contient aucun élément" dans Linq, non?
xSkrappy

34

Si vous voulez tout l'enregistrement, voici une méthode lambda:

var q = _context
             .lasttraces
             .GroupBy(s => s.AccountId)
             .Select(s => s.OrderByDescending(x => x.Date).FirstOrDefault());

1
A très bien fonctionné. Merci.
Terry

C'est la clé ici.
Jason P Sallinger

5

Cela pourrait être quelque chose comme:

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) };

3

Allez d'une manière simple de faire ceci: -

Création d'une classe pour contenir les informations suivantes

  • Niveau (nombre)
  • Url (URL du site)

Accédez à la liste des sites stockés sur un objet ArrayList. Et exécuté la requête suivante pour la trier par ordre décroissant par niveau.

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

Une fois que j'ai trié la collection par ordre décroissant, j'ai écrit le code suivant pour obtenir l'objet qui vient en haut

MyClass topObject = query.FirstRow<MyClass>()

Cela a fonctionné comme un charme.


Cela m'a donné une meilleure idée que ma pensée originale. Merci!
Paulj
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.