So erhalten Sie mit Linq den ersten Datensatz in jeder Gruppe

133

Berücksichtigung der folgenden Aufzeichnungen:

   Id          F1            F2             F3 
 -------------------------------------------------
   1           Nima          1990           10
   2           Nima          1990           11
   3           Nima          2000           12
   4           John          2001           1
   5           John          2002           2 
   6           Sara          2010           4

Ich möchte basierend auf dem F1Feld gruppieren und sortieren Idund alle Felder aus dem ersten Datensatz der Gruppe abrufen, die diesen Datensätzen ähnlich sind:

   Id          F1            F2             F3 
 -------------------------------------------------
   1           Nima          1990           10
   4           John          2001           1
   6           Sara          2010           4

Wie kann ich das mit linq machen?

Arian
quelle

Antworten:

127
    var res = from element in list
              group element by element.F1
                  into groups
                  select groups.OrderBy(p => p.F2).First();
Alireza
quelle
4
Ich bin so froh, dass ich das gefunden habe. Ich habe die Fehlermeldung "Die Methode 'First' kann nur als letzte Abfrageoperation verwendet werden. Verwenden Sie in diesem Fall stattdessen die Methode 'FirstOrDefault'." von Ihrem Beispiel. Nur die Operation in der Liste, die ich nach der Abfrage ausgeführt habe, hat myResult.ToList () an eine Methode übergeben. Die Verwendung von FirstOrDefault löste es jedoch
gegen den
Wäre es so OrderBy(p => p.Id), sie wollten es nach ID sortiert, nicht nach der Jahresspalte.
Mike Flynn
Können Sie bitte etwas Unterstützung dafür bereitstellen
Si8
Was ist, wenn Sie das erste und letzte Element aus der Gruppe abrufen möchten?
Sandeep Pandey
176
var result = input.GroupBy(x=>x.F1,(key,g)=>g.OrderBy(e=>e.F2).First());
König König
quelle
2
Dies zeigte mir den Weg mit der Fluent-Syntax. Die Überlastungen für GroupBy scheinen Ihnen viel Kraft zu geben - eine, die Sie zur langen Liste des Lernens hinzufügen können!
Rogersillito
1
@rogersillito Aus diesem Grund wird es als Abfrage bezeichnet (Language Integrated Query - LINQ). Außerdem hat das GroupBy viele Überladungen, aber es werden nur wenige häufig verwendet. Dies hängt auch von den persönlichen Vorlieben ab, z. B. schreiben einige es lieber als .GroupBy(x=>x.F1).Select(g=>...): es kann leichter zu verstehen aussehen.
König König
11
Sie sollten ersetzen .First()durch .FirstOrDefault()oder Sie erhalten die Ausnahme:The method 'First' can only be used as a final query operation. Consider using the method 'FirstOrDefault' in this instance instead.
Nikolay Kostov
5
@NikolayKostov Ich weiß darüber Bescheid, aber ich habe angenommen, dass der LINQ hier als LINQ-zu-Objekt und nicht als LINQ-zu-Entitäten verwendet wird, damit wir ihn sicher verwenden können .First(). Die Frage des OP sieht wirklich so aus, als würde er sich nur um Linq-to-Object kümmern, obwohl er die Frage auch mit markiert hat linq-to-entities(nicht sicher, ob er verstanden hat, was das ist).
König König
1
Ich mochte diese Antworten, Schöne.
Ajas Aju
8

Die Antwort von @Alireza ist völlig korrekt, aber Sie müssen dies beachten, wenn Sie diesen Code verwenden

var res = from element in list
          group element by element.F1
              into groups
              select groups.OrderBy(p => p.F2).First();

Dies ähnelt diesem Code, da Sie die Liste bestellen und dann die Gruppierung durchführen, sodass Sie die erste Gruppenreihe erhalten

var res = (from element in list)
          .OrderBy(x => x.F2)
          .GroupBy(x => x.F1)
          .Select()

Wenn Sie nun etwas Komplexeres tun möchten, z. B. dasselbe Gruppierungsergebnis, aber das erste Element von F2 und das letzte Element von F3 oder etwas Benutzerdefinierteres, können Sie dies tun, indem Sie den folgenden Code studieren

 var res = (from element in list)
          .GroupBy(x => x.F1)
          .Select(y => new
           {
             F1 = y.FirstOrDefault().F1;
             F2 = y.First().F2;
             F3 = y.Last().F3;
           });

So bekommen Sie so etwas wie

   F1            F2             F3 
 -----------------------------------
   Nima          1990           12
   John          2001           2
   Sara          2010           4
Stavros Koureas
quelle
Das Trennzeichen oder Trennzeichen des neuen Objekts sollte ein Komma und kein Semikolon sein. Bitte überprüfen.
Naredla Nithesh Reddy
3

Verwenden Sie es, um das zu erreichen, was Sie wollen. Entscheiden Sie dann, welche Eigenschaften Sie zurückgeben möchten.

yourList.OrderBy(l => l.Id).GroupBy(l => new { GroupName = l.F1}).Select(r => r.Key.GroupName)
Rubens Mussi Cury
quelle